简体   繁体   English

EF6 与 Sqlite 一对多关系在唯一约束上失败

[英]EF6 with Sqlite one-to-many relationship failing on Unique Constraint

I'm running into an issue when inserting entities with one-to-many relationships into an SQLite database using Entity Framework 6. Let's consider this example:使用 Entity Framework 6 将具有一对多关系的实体插入 SQLite 数据库时遇到问题。让我们考虑这个例子:

Model Model

public class Box {
    public int BoxId { get; set; }
    public ICollection<Item> Items{ get; set; }
}

public class Item {
    public int ItemId { get; set; }
    public Box Box { get; set; }
}

Insertion插入

Box box = new Box(){BoxId = 1};
Item item = new Item(){ItemId = 1, Box = box};
using (var db = new MyDbContext()) {
    db.Boxes.Add(box);
    db.SaveChanges();
    db.Items.Add(item);
    db.SaveChanges();
}

This snippet works.这个片段有效。

Box box = new Box(){BoxId = 1};
Item item = new Item(){ItemId = 1, Box = box};
using (var db = new MyDbContext()) {
    db.Boxes.Add(box);
    db.SaveChanges();
}
using (var db = new MyDbContext()) {
    db.Items.Add(item);
    db.SaveChanges();
}

This snippet doesn't work, throws an Exception with message UNIQUE constraint failed此代码段不起作用,引发异常,消息 UNIQUE 约束失败

I understand why it doesn't work, but I can't figure out a way to make it work.我明白为什么它不起作用,但我无法找到让它起作用的方法。 Using the same context is not an option, because the application could be restarted between the creation of the Box and the addition of an Item.使用相同的上下文不是一个选项,因为应用程序可能会在创建 Box 和添加 Item 之间重新启动。 I found an answer to the same question but using EF core instead of EF6 ( right there (Stack Overflow) ) but I can't access the TrackGraph property of the ChangeTracker with EF6.我找到了相同问题的答案,但使用的是 EF 核心而不是 EF6( 就在那里(堆栈溢出) ),但我无法使用 EF6 访问ChangeTrackerTrackGraph属性。

I would also need to have a fully generic way of solving this issue, because I could possibly have other objects in my Boxes than Items.我还需要有一个完全通用的方法来解决这个问题,因为我的 Boxes 中可能有其他对象而不是 Items。

Okay so I figured a way.好的,所以我想了一个办法。

Before calling db.SaveChanges() I execute this code, where entities is the list of entities I just added to the DbContext.在调用db.SaveChanges()之前,我执行此代码,其中实体是我刚刚添加到 DbContext 的实体列表。 This way only entities that I explicitly wanted to add are added, other related entities are not added, and thus I don't run into Unique constraint failed because DbContext is not recreating related entities.这样,只添加了我明确想要添加的实体,不添加其他相关实体,因此我不会遇到唯一约束失败,因为 DbContext 没有重新创建相关实体。

db.ChangeTracker.Entries().ToList().ForEach(dbe => {
    if (!entities.Contains(dbe.Entity)) {
        dbe.State = EntityState.Unchanged;
    }
});

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

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