实体框架代码优先导航问题
Posted
技术标签:
【中文标题】实体框架代码优先导航问题【英文标题】:Entity Framework Code First navigation issue 【发布时间】:2011-04-05 04:42:42 【问题描述】:我正在尝试设置一个导航属性,该属性将包含另一个表格的零个或多个元素。 Entity Framework 似乎遇到的问题是另一个表有一个复合主键。
public class Alpha
public int Id get; set;
public int? BetaId get; set;
public virtual ICollection<Beta> Beta get; set;
public string Name get; set;
public class Beta
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id get; set;
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int SequenceNumber get; set;
public string Name get; set;
public class ABContext : DbContext
public DbSet<Alpha> Alpha get; set;
public DbSet<Beta> Beta get; set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<Beta>()
.HasKey(b => new b.Id, b.SequenceNumber );
我不确定如何正确设置关系。我尝试了几种不同的方法。 Entity Framework 要么抱怨没有使用 Beta 类中的两个键来定义导航属性,要么在 Alphas 表中创建了一对未正确链接表的额外列。
目标是 Alpha 应持有一组基于 Beta.Id
的零个或多个 Beta。一个 Beta 可能属于零个或多个 Alpha。但是,我对 Beta 与 Alpha 的关系并不真正感兴趣。
有什么想法吗?
【问题讨论】:
为什么不使用 [Key] 属性指定您的密钥?而且即使你不感兴趣,将 Alpha 属性添加到 Beta 中也不会伤害任何人。 我可以使用[Key, Column(Order = #), ...]
,但它的作用与.HasKey()
完全相同。将public virtual ICollection<Alpha> Alpha get; set;
添加到类 Beta 会创建一个 BetaAlphas 查找表。我只想设置 Alpha.BetaId
并自动获取 Beta 集合。
【参考方案1】:
让我们来看看你的要求:
Alpha 应该包含零个或多个 Beta 的集合 .... 一个 Beta 可能属于零个或多个 Alpha
这是多对多的关系,所以你必须映射它。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<Beta>()
.HasKey(b => new b.Id, b.SequenceNumber );
modelBuilder.Entity<Alpha>()
.HasMany(a => a.Beta)
.WithMany();
这将在数据库中创建具有三列的附加表(可能称为 Alpha_Id、Beta_Id 和 Beta_SequenceNumber)。
我仍然不明白基于 Beta.Id 是什么意思。如果 alpha 只能保存具有相同 Beta.Id 的记录,您可能必须在应用程序逻辑中控制它。这需要通过映射来实施额外的复杂构造。
【讨论】:
Beta 中的 Id 属性本质上是一个组 id。一个 Alpha 对象可能有一组特定的 Beta 对象。我试图避免使用查找表,因为我在 242 个组中有 700,000 多个 Alpha 对象和 120,000 多个 Beta 对象。 您不会避免查找表,因为您的关系需要它。 我尝试了几种不同的方法,但都没有奏效。我最终将 Beta 查找移至存储库并添加了modelBuilder.Entity<Alpha>().Ignore(a => a.Beta);
。这会阻止 EF 添加额外的列或查找表。唯一的缺点是现在必须手动填写 Beta 集合。以上是关于实体框架代码优先导航问题的主要内容,如果未能解决你的问题,请参考以下文章