多对多自定义连接实体

我不得不承认,我真的不喜欢让 EF 推断连接表没有加入实体。你无法跟踪人车关联的额外信息(假设它的有效日期),因为你无法修改该表。

此外,连接表中的 CarId 是主键的一部分,因此如果家庭购买新车,则必须先删除旧关联并添加新关联。EF 隐藏了这一点,但这意味着你必须执行这两个操作而不是简单的更新(更不用说频繁的插入/删除可能会导致索引碎片 - 好的方法是有一个简单的解决方法)。

在这种情况下,你可以创建一个连接实体,该实体可以引用一个特定的汽车和一个特定的人。基本上,你将多对多关联视为两个一对多关联的组合:

public class PersonToCar
{
   public int PersonToCarId { get; set; }
   public int CarId { get; set; }
   public virtual Car Car { get; set; }
   public int PersonId { get; set; }
   public virtual Person Person { get; set; }
   public DateTime ValidFrom { get; set; }
}

public class Person
{
  public int PersonId { get; set; }
  public string Name { get; set; }
  public virtual ICollection<PersonToCar> CarOwnerShips { get; set; }
}

public class Car
{
  public int CarId { get; set; }
  public string LicensePlate { get; set; }        
  public virtual ICollection<PersonToCar> Ownerships { get; set; }
}

public class MyDemoContext : DbContext
{
  public DbSet<Person> People { get; set; }
  public DbSet<Car> Cars { get; set; }
  public DbSet<PersonToCar> PersonToCars { get; set; }
}

这给了我更多的控制权,而且更加灵活。我现在可以向关联添加自定义数据,并且每个关联都有自己的主键,因此我可以更新汽车或其中的所有者引用。

请注意,这实际上只是两个一对多关系的组合,因此你可以使用前面示例中讨论的所有配置选项。