在实体框架6中保存分离的对象图的正确顺序是什么?

时间:2018-10-11 15:25:36

标签: c# entity-framework entity-framework-6

我正在使用实体框架保存复杂的分离对象。我从Web API检索对象,然后将json反序列化为c#对象。 我实体的一部分的简化版本如下:

class Order{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    long Id {get; set; }

    [ForeignKey("Billing")]
    long BillingId { get; set; }

    Address Billing { get; set; }

    [ForeignKey("Shipping")]
    long ShippingId { get; set; }

    Address Shipping{ get; set; }
}

class Address{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    long Id { get; set;}

    [ForeignKey("Country")]
    long CountryId { get; set; }

    Country Country { get; set; }
}

class Country{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    long Id { get; set;} 
}

我遍历对象图,尝试确定哪些对象必须插入,哪些对象需要更新。使用以下代码(实际代码运行时具有通用函数,我只是将它们全部写出来以更好地掌握它):

Order order = restClient.Get<Order>(1);
using(var context = new MyContext()){
    if (order.Billing != null){
        if(order.Billing.Country != null){
                var dbBillingCountry = context.Set<Country>().Find(order.Billing.Country.Id);
                if(dbBillingCountry == null){
                    context.Set<Country>().Add(order.Billing.Country);
                }
                else{
                    context.Entry(dbBillingCountry).CurrentValues.SetValues(order.Billing.Country);
                    //order.Billing.Country = dbBillingCountry;
                    context.Entry(dbBillingCountry).State = EntityState.Modified;
                }
        }

        var dbBilling = context.Set<Address>().Find(order.Billing.Id);
        if(dbBilling == null){
            context.Set<Address>().Add(order.Billing);
        }
        else{
            context.Entry(dbBilling).CurrentValues.SetValues(order.Billing);
            //order.Billing = dbBilling;
            context.Entry(dbBilling).State = EntityState.Modified;
        }
        //db.SaveChanges();
    }
    if (order.Shipping != null){
        if(order.Shipping.Country != null){
                var dbShippingCountry = context.Set<Country>().Find(order.Shipping.Country.Id);
                if(dbShippingCountry == null){
                    context.Set<Country>().Add(order.Shipping.Country);
                }
                else{
                    context.Entry(dbShippingCountry).CurrentValues.SetValues(order.Shipping.Country);
                    //order.Shipping.Country = dbShippingCountry;
                    context.Entry(dbShippingCountry).State = EntityState.Modified;
                }
        }
        var dbShipping = context.Set<Address>().Find(order.Shipping.Id);
        if(dbShipping == null){
            context.Set<Address>().Add(order.Shipping);
        }
        else{
            context.Entry(dbShipping).CurrentValues.SetValues(order.Shipping);
            //order.Shipping = dbShipping;
            context.Entry(dbShipping).State = EntityState.Modified;
        }
        //db.SaveChanges();
    }
    var dbOrder = context.Set<Order>().Find(order.Id);
    if(dbOrder == null){
        context.Set<Order>().Add(order);
    }
    else{
        context.Entry(dbOrder).CurrentValues.SetValues(order);
        //order = dbOrder;
        context.Entry(dbOrder).State = EntityState.Modified;
    }
context.SaveChanges();
}

order.Billingorder.Shipping中的context.SaveChanges()是相同的对象/值的情况下,我收到一个错误,因为EF尝试插入该地址,在此之前,该国家使用相同的地址两次键。 我尝试设置contex.Find返回的数据库/本地实体的引用,但这并不能解决。 我怎么能告诉上下文,这些是相同的对象?

0 个答案:

没有答案