Entity Framework - 父子关系 table
Entity Framework - Parent Child relational table
我有一个组织实体 table
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public OrganizationType OrganizationType { get; set; }
public ICollection<OrganizationRelation> OrganizationRelations { get; set; }
}
然后我有我的关系 table 和一个自引用父列
public class OrganizationRelation
{
public int OrganizationRelationId { get; set; }
public int OrganizationId { get; set; }
public int? ParentOrganizationId { get; set; }
public Organization Organization { get; set; }
public Organization ParentOrganization { get; set; }
}
public class OrganizationRelationModelConfiguration : IEntityTypeConfiguration<OrganizationRelation>
{
public void Configure(EntityTypeBuilder<OrganizationRelation> builder)
{
builder.HasKey(c => c.OrganizationRelationId);
builder.Property(c => c.OrganizationRelationId).ValueGeneratedOnAdd();
builder.Property(c => c.OrganizationId).IsRequired();
builder.Property(c => c.ParentOrganizationId);
builder.HasOne(r => r.Organization).WithMany().HasForeignKey(fk => fk.OrganizationId);
builder.HasOne(r => r.ParentOrganization).WithMany().HasForeignKey(fk => fk.ParentOrganizationId);
builder.ToTable("OrganizationRelation", "dbo");
}
}
当我使用迁移部署我的数据库时,我看到 table 创建了:
CREATE TABLE [mdo].[OrganizationRelation](
[OrganizationRelationId] [int] IDENTITY(1,1) NOT NULL,
[OrganizationId] [int] NOT NULL,
[ParentOrganizationId] [int] NULL,
[OrganizationId1] [int] NULL,
CONSTRAINT [PK_OrganizationRelation] PRIMARY KEY CLUSTERED
(
[OrganizationRelationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我正在使用 EF 5.0
我不明白为什么要创建列 OrganizationId1
您没有将 OrganizationRelation.ParentOrganization
映射到 Organization.OrganizationRelations
,因此 EF 正在为第二个导航 属性 添加一个额外的 FK 到 OrganizationRelation
。
但该模型似乎过于复杂。为什么不
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public int? ParentOrganizationId { get; set; }
public Organization ParentOrganization { get; set; }
public ICollection<Organization> ChildOrganizations{ get; } = new HashSet<Organization>();
}
这创造了
CREATE TABLE [Organization] (
[OrganizationId] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[OrganizationTypeId] int NOT NULL,
[ParentOrganizationId] int NULL,
CONSTRAINT [PK_Organization] PRIMARY KEY ([OrganizationId]),
CONSTRAINT [FK_Organization_Organization_ParentOrganizationId] FOREIGN KEY ([ParentOrganizationId]) REFERENCES [Organization] ([OrganizationId]) ON DELETE NO ACTION
);
CREATE INDEX [IX_Organization_ParentOrganizationId] ON [Organization] ([ParentOrganizationId]);
?
要将外键分解为单独的 table,您只需引入 1-1 依赖项 table,其中依赖项 table 的 FK 和 PK 相同作为主要table的PK。
所以用一个单独的实体做同样的事情看起来像这样:
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public OrganizationRelation OrganizationRelation { get; set; }
public ICollection<OrganizationRelation> ChildOrganizations { get; } = new HashSet<OrganizationRelation>();
}
public class OrganizationRelation
{
public int OrganizationId { get; set; }
public int ParentOrganizationId { get; set; }
public Organization Organization { get; set; }
public Organization ParentOrganization { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OrganizationRelation>().HasKey(c => c.OrganizationId);
builder.Entity<OrganizationRelation>()
.HasOne(r => r.Organization)
.WithOne(o => o.OrganizationRelation)
.HasForeignKey(nameof(OrganizationRelation), nameof(OrganizationRelation.OrganizationId));
builder.Entity<OrganizationRelation>()
.HasOne(r => r.ParentOrganization)
.WithMany(o => o.ChildOrganizations)
.HasForeignKey(r => r.ParentOrganizationId)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<OrganizationRelation>().ToTable("OrganizationRelation", "dbo");
base.OnModelCreating(builder);
}
我有一个组织实体 table
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public OrganizationType OrganizationType { get; set; }
public ICollection<OrganizationRelation> OrganizationRelations { get; set; }
}
然后我有我的关系 table 和一个自引用父列
public class OrganizationRelation
{
public int OrganizationRelationId { get; set; }
public int OrganizationId { get; set; }
public int? ParentOrganizationId { get; set; }
public Organization Organization { get; set; }
public Organization ParentOrganization { get; set; }
}
public class OrganizationRelationModelConfiguration : IEntityTypeConfiguration<OrganizationRelation>
{
public void Configure(EntityTypeBuilder<OrganizationRelation> builder)
{
builder.HasKey(c => c.OrganizationRelationId);
builder.Property(c => c.OrganizationRelationId).ValueGeneratedOnAdd();
builder.Property(c => c.OrganizationId).IsRequired();
builder.Property(c => c.ParentOrganizationId);
builder.HasOne(r => r.Organization).WithMany().HasForeignKey(fk => fk.OrganizationId);
builder.HasOne(r => r.ParentOrganization).WithMany().HasForeignKey(fk => fk.ParentOrganizationId);
builder.ToTable("OrganizationRelation", "dbo");
}
}
当我使用迁移部署我的数据库时,我看到 table 创建了:
CREATE TABLE [mdo].[OrganizationRelation](
[OrganizationRelationId] [int] IDENTITY(1,1) NOT NULL,
[OrganizationId] [int] NOT NULL,
[ParentOrganizationId] [int] NULL,
[OrganizationId1] [int] NULL,
CONSTRAINT [PK_OrganizationRelation] PRIMARY KEY CLUSTERED
(
[OrganizationRelationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我正在使用 EF 5.0 我不明白为什么要创建列 OrganizationId1
您没有将 OrganizationRelation.ParentOrganization
映射到 Organization.OrganizationRelations
,因此 EF 正在为第二个导航 属性 添加一个额外的 FK 到 OrganizationRelation
。
但该模型似乎过于复杂。为什么不
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public int? ParentOrganizationId { get; set; }
public Organization ParentOrganization { get; set; }
public ICollection<Organization> ChildOrganizations{ get; } = new HashSet<Organization>();
}
这创造了
CREATE TABLE [Organization] (
[OrganizationId] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[OrganizationTypeId] int NOT NULL,
[ParentOrganizationId] int NULL,
CONSTRAINT [PK_Organization] PRIMARY KEY ([OrganizationId]),
CONSTRAINT [FK_Organization_Organization_ParentOrganizationId] FOREIGN KEY ([ParentOrganizationId]) REFERENCES [Organization] ([OrganizationId]) ON DELETE NO ACTION
);
CREATE INDEX [IX_Organization_ParentOrganizationId] ON [Organization] ([ParentOrganizationId]);
?
要将外键分解为单独的 table,您只需引入 1-1 依赖项 table,其中依赖项 table 的 FK 和 PK 相同作为主要table的PK。
所以用一个单独的实体做同样的事情看起来像这样:
public class Organization
{
public int OrganizationId { get; set; }
public string Name { get; set; }
public int OrganizationTypeId { get; set; }
public OrganizationRelation OrganizationRelation { get; set; }
public ICollection<OrganizationRelation> ChildOrganizations { get; } = new HashSet<OrganizationRelation>();
}
public class OrganizationRelation
{
public int OrganizationId { get; set; }
public int ParentOrganizationId { get; set; }
public Organization Organization { get; set; }
public Organization ParentOrganization { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OrganizationRelation>().HasKey(c => c.OrganizationId);
builder.Entity<OrganizationRelation>()
.HasOne(r => r.Organization)
.WithOne(o => o.OrganizationRelation)
.HasForeignKey(nameof(OrganizationRelation), nameof(OrganizationRelation.OrganizationId));
builder.Entity<OrganizationRelation>()
.HasOne(r => r.ParentOrganization)
.WithMany(o => o.ChildOrganizations)
.HasForeignKey(r => r.ParentOrganizationId)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<OrganizationRelation>().ToTable("OrganizationRelation", "dbo");
base.OnModelCreating(builder);
}