繁体   English   中英

具有数据库优先多对多关系问题的实体框架 6

[英]Entity Framework 6 with Database-First Many to Many relationship problem

我首先使用多对多关系模式在使用 EF 6 DB 时遇到了一些问题。 这是一个简化的示例:

public partial class Person
{
    public int Id { get; set; }
    public string Name{ get; set; }
    public virtual ICollection<Car> Cars { get; set; }
}

public partial class Car
{
    public Car()
    {
        this.People = new HashSet<Person>();
        this.Tires = new HashSet<Tire>();
    }

    public int Id { get; set; }
    public string Model{ get; set; }
    public string Make { get; set; }
    public virtual ICollection<Person> People { get; set; }
    public virtual ICollection<Tire> Tires { get; set; }
}

public partial class Tire
{
    public Tire()
    {
        this.Cars = new HashSet<Car>();
    }

    public string Model{ get; set; }
    public int Size { get; set; }
    public virtual ICollection<Car> Cars{ get; set; }
}

为此,数据库中有五个表:


人车测绘

汽车轮胎测绘

三个用于存储数据的表和两个用于映射/关联数据的表。 当我创建一个人 object,用数据填充它并尝试保存它时,就会出现我的问题。

一个人可能有多辆汽车,一辆汽车可能有不同的 model 轮胎,因此是多对多映射。 如果我创建一个人 object,有多辆车,但其中几辆车具有相同的 Model 轮胎(轮胎表的 PK),EF 不会首先检查轮胎 Z20F35E630DAF44DBFA4C3F68 的一部分object(通过关联),并尝试将其两次或多次添加到轮胎表中。 实际上,只需要修改映射表以显示 Car 和(已经存在的)轮胎之间的新映射。

所以在构建了一个人 object 之后,有多辆汽车,多轮胎的汽车等并尝试:

context.Person.Add(personObject)
context.SaveChanges();

在轮胎表上给出主键冲突错误。 我错过了什么?
EF 似乎只通过从映射表中删除来处理删除,但添加给我带来了问题。

[编辑]
我将对此进行一些更改,因为我找到了解决原始问题的解决方案,但出现了类似的问题。

以下是我将如何构建几个人对象:

Person p1 = new Person() { Id = 1, Name = "Joe" }
Car car1 = new Car() { Id = 1, Make = "Honda", Model = "Accord" } 
Car car2 = new Car() { Id = 2, Make = "Honda", Model = "Civic" }
Tire tire1 = new Tire() { Model = "ModelA", Size = 16 }
car1.Tires.Add(tire1);
p1.Cars.Add(car1);
p1.Cars.Add(car2);

Person p2 = new Person() { Id = 2, Name = "Bob" }
Car car3 = new Car() { Id = 1, Make = "Honda", Model = "Accord" } 
p1.Cars.Add(car3);

// Finally
context.Person.Add(p1);
context.SaveChanges();   // Necessary to save twice.  Don't ask.

context.Person.Add(p2);
context.SaveChanges();

这会引发主键冲突,因为它会在保存 p2 时尝试添加 ID 为 1 的 Car。 有没有办法让 EF 足够聪明,以实现只需要添加关联表,并且 Car 表本身不需要被触及,因为 ID 为 1 的 Car 已经存在于 Car 表中?

您可以在调用 SaveChanges 之前指定实体 state。

context.Entry(existingCar).State = EntityState.Unchanged;


EF 处理引用。 对具有相同密钥的 object 的两个不同引用不被视为同一事物:

Person p1 = new Person() { Id = 1, Name = "Joe" }
Car car1 = new Car() { Id = 1, Make = "Honda", Model = "Accord" } 
p1.Cars.Add(car1);

Person p2 = new Person() { Id = 2, Name = "Bob" }
Car car3 = new Car() { Id = 1, Make = "Honda", Model = "Accord" } 
p2.Cars.Add(car3);

汽车 1 和 3 是两个独立的引用,但指向汽车 ID=1。 我认为您的示例中有一个错误,它有p1.Cars.Add(car3)而不是 p2。 无论哪种方式,问题都在于两个汽车实例。 反而:

Person p2 = new Person() { Id = 2, Name = "Bob" }
p2.Cars.Add(car1);

现在,汽车 ID 1 将在人员 1 和人员 2 之间正确引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM