【发布时间】:2013-09-22 07:33:41
【问题描述】:
如何在 Entity Framework 5 中映射以下关系?
public class Item {
public int Id { get; set; }
public int? ParentItemId { get; set; }
public string Value { get; set; }
public Item ParentItem { get; set; }
public List<Item> ChildItems { get; set; }
}
我试过了:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Item>()
.HasOptional(i => i.ParentItem)
.WithMany(i => i.ChildItems)
.HasForeignKey(i => i.ParentItemId);
}
还有这个:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Item>()
.HasMany(i => i.ChildItems)
.WithOptional(i => i.ParentItem)
.HasForeignKey(i => i.ParentItemId);
}
两者都会导致此错误:
引用约束的Dependent Role中所有属性的类型必须与Principal Role中对应的属性类型相同。
如果我从数据库优先映射开始,生成的实体如下所示:
public partial class Item
{
public Item()
{
this.ChildItems = new HashSet<Item>();
}
public int Id { get; set; }
public Nullable<int> ParentItemId { get; set; }
public string Value { get; set; }
public virtual ICollection<Item> ChildItems { get; set; }
public virtual Item ParentItem { get; set; }
}
我知道如果我从 db-first 开始这将起作用,我只需要知道如何在 code-first 中定义关系。
【问题讨论】:
-
Id是关键属性吗?或者您是否有到另一个属性的键映射(使用 Fluent API?),例如到Value? -
Id是Item的主键属性。
-
“从属角色中所有属性的类型”表示FK属性的类型,即
ParentItemId,类型为int?。 “Principal Role 中对应的属性类型”是指Id类型为int的PK 属性类型。它们是相同的(可空性无关紧要)。但是,例外说,它们不是。例如,如果您有一个用于 PK 的long(或任何其他类型)和一个用于 FK 的int?,则会发生异常。比较奇怪…… -
我已经复制了您发布的代码并运行它,它在我的系统上运行没有错误。我可以创建和读取项目,没有抛出异常。我正在使用 VS2013 RC 和 EF 6
-
@Slauma 这就是问题所在。我在这里发布了问题的简化表示(因为真实实体很大),但 Item 的主键实际上被标记为 long。感谢您指出了这一点。请发表回复,我会将其标记为答案。
标签: c# entity-framework foreign-keys entity-framework-5