Я работаю над сохранением сложных отдельных объектов в рамках сущности.Я извлекаю объекты из веб-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
, но это не исправляет.Как я могу сказать контексту, что это одни и те же объекты?