EF Core / Sqlite one-to-many relationship failing on Unique Index Constraint

后端 未结 2 369
花落未央
花落未央 2021-01-14 03:21

The context is each Car has a corresponding CarBrand. Now my classes are as shown below:

public class Car
{
    public int CarId {          


        
2条回答
  •  一生所求
    2021-01-14 03:39

    Quickfix:

    EntityFramework Core has problem with your code using new Context inside using of another one. You're mixing states of entities between the two of them. Just use the same context for fetching and creating. If you go with:

    using (var context = new MyContext())
    {
        var honda = context.CarBrands.Find(1);
        var car2 = new Car() { CarBrand = honda };
        context.Cars.Add(car2);
        context.SaveChanges(); //fine now
        var cars = context.Cars.ToList(); //will get two
    }
    

    it should be fine.


    If you really want to got for two contexts

        static void Main(string[] args)
        {
            AlwaysCreateNewDatabase();
    
            CarBrand hondaDb = null;
            using (var context = new MyContext())
            {
                hondaDb = context.CarBrands.Add(new CarBrand {Name = "Honda"}).Entity;
                context.SaveChanges();
            }
    
            using (var context = new MyContext())
            {
                var car2 = new Car() { CarBrandId = hondaDb.CarBrandId };
                context.Cars.Add(car2);
                context.SaveChanges();
            }
        }
    

    You do not depend on change tracking mechanics now but rather on plain FOREIGN KEY relation based on CarBrandId.


    Reason: Change tracking

    Error might be misleading but if you look inside StateManager of your context, you'll see the reason. Because CarBrand you fetched from another Context is the one you're using, for another instance of Context it looks like a new one. You can clearly see it in debug with property EntityState of that particular entity in this particular DB context:

    It says that CarBrand is now being Added to database with Id: 1 and that's the UNIQUE constrain of PRIMARY KEY of CarBrand table being broken.

    Error says its CarBrandId breaking the constrain because you forced creation of new record in database through relation Car-CarBrand that is backed by CarBrandId.

    What would be the state of CarBrand with Id: 1 in context you used to query database? Unchanged of course. But that's the only Context that knows about it:

    If you want to go deeper into the topic, read about concept of Change Tracking in EF Core here: https://docs.microsoft.com/en-us/ef/core/querying/tracking

提交回复
热议问题