编程语言
首页 > 编程语言> > c#-使用默认约定具有可选依赖端的一对一关系

c#-使用默认约定具有可选依赖端的一对一关系

作者:互联网

我希望使用实体框架代码优先模型中的默认约定映射一个主体实体(人)和可选的依赖实体(汽车).

this answer中描述了一种解决方案,该解决方案使用modelBuilder上的流畅API映射到密钥.

是否可以仅使用默认的EF约定来执行此操作?以下代码将引发无法确定类型Person和Car之间的关联的主要终点.无效的操作异常.

public DatabaseContext : DbContext
  public DbSet<Person> Persons { get; set; }
  public DbSet<Car> Cars { get; set; }
  // No OnModelCreating - possible?

public class Person
  public Int32 PersonId { get; set; }
  public Int32? CarId { get; set; } // Optional.
  public virtual Car Car { get; set; }

public class Car
  public Int32 CarId { get; set; }
  public Int32 PersonId { get; set; }
  public virtual Person Person { get; set; }

此示例假定一个人只能与一个汽车或一个汽车不相关.我应该在没有相关人员的情况下插入汽车,但是我应该在没有相关人员的情况下插入汽车.为什么EF不能弄清楚CarId on person是Car的外键,反之亦然?

我在.NET Framework 4.5上使用Entity Framework 6.1.2.

流利的API缺点

当我尝试使用fluent API定义关系时,它可以工作,但是无法将键映射到现有列,这就是为什么我要首先使用约定的原因.我得到的例外是类型中的每个属性名称都必须是唯一的.

modelBuilder.Entity<Person>().HasOptional(p => p.Car).WithRequired(c => c.Person).Map(a => a.MapKey("PersonId"));

如果我忽略了MapKey调用,则SaveChanges成功,但是数据库检查显示Car行的PersonId外键列包含0,而不是1,即Person行中的PersonId主键列.

解决方法:

实体框架不支持一对一的外键关联.您必须删除外键属性并使用导航属性.通过这种方式映射您的关系:

modelBuilder.Entity<Person>().HasOptional(p => p.Car).WithRequired(c => c.Person);

EF将为您创建FK:

这是由于Entity Framework的要求,将依赖项(人)的主键用作外键.

标签:one-to-one,ef-code-first,foreign-key-relationship,c,entity-framework
来源: https://codeday.me/bug/20191028/1955071.html