Entity Framework Code First 的半递归关联
Semi-recursive associations with Entity Framework Code First
我希望你能帮助我解决我遇到的一个小问题。
我有一个 entity framework Code First 设置,其中我有以下设置:
public class UserDetails{
public int Id {get;set;}
//... some other properties .. //
//This represents the approval group the user is a member of.
public virtual ApprovalGroup {get;set;}
//This represents the approval groups that the user is resposible for approving
public virual ICollection<ApprovalGroup> ApprovalGroups {get;set;}
}
public class ApprovalGroup
{
public int Id {get;set;}
public string Name {get;set;}
public virtual UserDetails Approvee {get;set;}
public virtual ICollection<UserDetails> Members {get;set;}
}
在我的数据库上下文中,我有以下内容:
modelBuilder.Entity<ApprovalGroup>().ToTable("ApprovalGroup")
.HasKey(t=>t.Id)
.HasRequired(t=>t.Approver);
modelBuilder.Entity<ApprovalGroup>().HasMany(t=>t.Members)
.WithOptional().WillCascadeOnDelete(false);
因此批准组必须有一个批准者设置,但它可能没有成员(特别是在首次配置时)。
此代码是 运行,但是当我检查它创建的数据库时,批准组 table 中有一个名为 "UserDetails_Id" 的额外列。它被设置为外键,但它始终为空。
它创建的 table 的架构包含以下列:
Id, Name, UserDetails_Id, Approver_Id
我不知道为什么它会创建不必要的 table "UserDetails_Id",我希望它不要这样做,因为没有理由这样做。我怀疑我的 configuration/mapping 行为有问题,但我不知道是什么。
到目前为止,google 未能阐明我做错了什么,所以如果这里有人可以提供帮助,我们将不胜感激。
尼克
您遇到的问题是由于 improper/incomplete 关系映射以及 EF 默认约定。
我建议您始终单独配置关系,每个关系仅配置一次,并使用与导航和显式 FK 属性的 presence/absence 完全匹配的重载。
在这种特殊情况下,您有两个 one-to-many
双向(即两端都有导航属性)关系,没有明确的 FK 属性。所以正确的配置应该是这样的:
// Entities
modelBuilder.Entity<ApprovalGroup>()
.ToTable("ApprovalGroup")
.HasKey(t => t.Id);
modelBuilder.Entity<UserDetails>()
.ToTable("UserDetails")
.HasKey(t => t.Id);
// Relationships
modelBuilder.Entity<ApprovalGroup>()
.HasRequired(t => t.Approver)
.WithMany(t => t.ApprovalGroups);
modelBuilder.Entity<ApprovalGroup>()
.HasMany(t => t.Members)
.WithOptional(t => t.ApprovalGroup) // or whatever the name of the navigation property is (it's missing in the posted code)
.WillCascadeOnDelete(false);
我希望你能帮助我解决我遇到的一个小问题。
我有一个 entity framework Code First 设置,其中我有以下设置:
public class UserDetails{
public int Id {get;set;}
//... some other properties .. //
//This represents the approval group the user is a member of.
public virtual ApprovalGroup {get;set;}
//This represents the approval groups that the user is resposible for approving
public virual ICollection<ApprovalGroup> ApprovalGroups {get;set;}
}
public class ApprovalGroup
{
public int Id {get;set;}
public string Name {get;set;}
public virtual UserDetails Approvee {get;set;}
public virtual ICollection<UserDetails> Members {get;set;}
}
在我的数据库上下文中,我有以下内容:
modelBuilder.Entity<ApprovalGroup>().ToTable("ApprovalGroup")
.HasKey(t=>t.Id)
.HasRequired(t=>t.Approver);
modelBuilder.Entity<ApprovalGroup>().HasMany(t=>t.Members)
.WithOptional().WillCascadeOnDelete(false);
因此批准组必须有一个批准者设置,但它可能没有成员(特别是在首次配置时)。
此代码是 运行,但是当我检查它创建的数据库时,批准组 table 中有一个名为 "UserDetails_Id" 的额外列。它被设置为外键,但它始终为空。
它创建的 table 的架构包含以下列:
Id, Name, UserDetails_Id, Approver_Id
我不知道为什么它会创建不必要的 table "UserDetails_Id",我希望它不要这样做,因为没有理由这样做。我怀疑我的 configuration/mapping 行为有问题,但我不知道是什么。
到目前为止,google 未能阐明我做错了什么,所以如果这里有人可以提供帮助,我们将不胜感激。
尼克
您遇到的问题是由于 improper/incomplete 关系映射以及 EF 默认约定。
我建议您始终单独配置关系,每个关系仅配置一次,并使用与导航和显式 FK 属性的 presence/absence 完全匹配的重载。
在这种特殊情况下,您有两个 one-to-many
双向(即两端都有导航属性)关系,没有明确的 FK 属性。所以正确的配置应该是这样的:
// Entities
modelBuilder.Entity<ApprovalGroup>()
.ToTable("ApprovalGroup")
.HasKey(t => t.Id);
modelBuilder.Entity<UserDetails>()
.ToTable("UserDetails")
.HasKey(t => t.Id);
// Relationships
modelBuilder.Entity<ApprovalGroup>()
.HasRequired(t => t.Approver)
.WithMany(t => t.ApprovalGroups);
modelBuilder.Entity<ApprovalGroup>()
.HasMany(t => t.Members)
.WithOptional(t => t.ApprovalGroup) // or whatever the name of the navigation property is (it's missing in the posted code)
.WillCascadeOnDelete(false);