Ho dato un'occhiata ad alcune delle risposte a domande simili e non sembrano corrispondere alle mie.Aggiunta di un nuovo oggetto figlio mentre si modifica l'Entity Framework esistente per i bambini
Sto cercando di incorporare un modello da Entity Framework: DbContext (pagina 90) e non sembra funzionare. Il codice che sto utilizzando è il seguente:
[HttpPost]
public ActionResult Edit(Order order)
{
if (ModelState.IsValid)
{
db.Orders.Add(order);
db.Entry(order).State = EntityState.Modified;
foreach (var orderDetail in order.OrderDetails)
{
if (orderDetail.OrderId == 0)
{
db.Entry(orderDetail).State = EntityState.Added;
}
else
{
db.Entry(orderDetail).State = EntityState.Modified;
}
// The example order that I'm updating has two child entities
// so this orderId will be for the third, added one.
int addedOrderDetailId = order.OrderDetails[2].OrderId;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "CompanyName", order.CustomerId);
return View(order);
}
Ho corso un esempio in cui l'oggetto Ordine ha due oggetti OrderDetail esistenti e sto cercando di aggiungere un terzo. Ho incluso la variabileOrderDetailId aggiunta, in modo da poterla aggiungere al 'Watch' e vedere quando è stata modificata
Quello che ho trovato sta accadendo è l'OrderId dell'oggetto OrderDetail aggiunto (che è 0 quando il ciclo foreach è inserito) viene aggiornato dalla struttura dell'entità al OrderId dell'oggetto Order. Ciò avviene dopo la prima iterazione attraverso il ciclo foreach (quando la prima entità figlio ha il suo stato modificato in modificato. Ciò significa che tutti e tre i bambini vengono contrassegnati come modificati. Ciò sta facendo sì che SaveChanges() tenti di aggiornare una voce nel database che non esiste
Se qualcun altro ha avuto questo problema, allora sarei grato per qualsiasi consiglio su come aggirare questo. Dovrò anche affrontare gli oggetti figlio esistenti che vengono eliminati, ma io non hanno ancora ottenuto intorno a questo, quindi se qualcuno sa di un modello per questo, che sarebbe anche apprezzato
Edit:.
Dopo aver preso il consiglio di Slauma e la rimozione db.Or ders.Add (ordine). Sono stato in grado di spostare la chiamata a db.Entry (order) .State sotto il ciclo foreach. Ciò mi ha permesso di scorrere il ciclo e impostare lo stato di ogni oggetto OrderDetail da modificare per quelli esistenti e aggiunto per quello aggiunto. Ho quindi dovuto semplicemente assegnare l'OrderId del genitore al OrderId del bambino e l'aggiornamento è andato a buon fine. Ho anche incluso il codice che ho usato per eliminare oggetti figlio durante la modifica. Non sono sicuro di quanto sia efficiente, ma funziona. Ecco il codice rivisto:
[HttpPost]
public ActionResult Edit(Order order)
{
if (ModelState.IsValid)
{
List<int> previousProductIds = db.OrderDetails
.Where(ep => ep.OrderId == order.OrderId)
.Select(ep => ep.ProductId)
.ToList();
List<int> currentProductIds = order.OrderDetails
.Select(o => o.ProductId)
.ToList();
List<int> deletedProductIds = previousProductIds
.Except(currentProductIds).ToList();
foreach (var deletedProductId in deletedProductIds)
{
OrderDetail deletedOrderDetail = db.OrderDetails
.Where(od => od.OrderId == order.OrderId && od.ProductId == deletedProductId)
.Single();
db.Entry(deletedOrderDetail).State = EntityState.Deleted;
}
foreach (var orderDetail in order.OrderDetails)
{
if (orderDetail.OrderId == 0)
{
db.Entry(orderDetail).State = EntityState.Added;
orderDetail.OrderId = order.OrderId;
}
else
{
db.Entry(orderDetail).State = EntityState.Modified;
}
}
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "CompanyName", order.CustomerId);
return View(order);
}
Grazie per la domanda. In realtà il tuo codice mi ha aiutato a darmi una soluzione semplice per aggiornare o inserire i figli di un'entità. Taglia e incolla, ha funzionato la prima volta, fatto il lavoro. +1 –