我正在使用实体框架保存复杂的分离对象。我从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.Billing
与order.Shipping
中的context.SaveChanges()
是相同的对象/值的情况下,我收到一个错误,因为EF尝试插入该地址,在此之前,该国家使用相同的地址两次键。
我尝试设置contex.Find
返回的数据库/本地实体的引用,但这并不能解决。
我怎么能告诉上下文,这些是相同的对象?