简体   繁体   中英

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:

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

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. 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.

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.

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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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