2011-10-18 9 views
5

Sto utilizzando il codice del framework di entità per primo ed espongo il database northwind tramite un'interfaccia HTTP REST WCF.Ricollegamento di un grafico di entità e rilevamento delle modifiche alla raccolta

Non ho esposto la tabella OrderDetails (articoli dell'ordine) in quanto non ha senso creare un ordine e quindi aggiungere separatamente ciascun OrderDetail richiesto tramite un altro servizio. A mio avviso, deve essere una transazione atomica che ha esito positivo o negativo. Pertanto includo la raccolta Order.OrderDetails quando si passa al client e presumo che ne avrò uno quando viene creato o aggiornato un ordine.

Il problema sembra tuttavia rilevare le modifiche alla raccolta OrderDetails quando si ricollega l'entità Ordine per un aggiornamento. L'ordine stesso può essere impostato come modificato per aggiornare tali proprietà, ma questo non si sovrappone agli elementi OrderDetail. Quindi posso passare manualmente e impostare quelli aggiornati a modificati, ma il problema sta nel capire quali sono aggiornati in primo luogo. L'impostazione di un nuovo OrderDetail da modificare causerà un errore durante il tentativo di salvataggio.

Ho letto un consiglio per impostare l'ID dei nuovi elementi della raccolta su 0 e nel server utilizzare quello per decidere se è nuovo o esistente. Northwind tuttavia utilizza una chiave composta tra OrderID e ProductID per OrderDetails. Questi dovranno essere entrambi impostati dal cliente, quindi non riesco a trovare un modo per rilevare cosa è nuovo. Inoltre, un OrderDetail cancellato non esiste nel grafico separato e dovrò capire cosa è stato cancellato e rimuoverlo esplicitamente.

Qualsiasi consiglio sarebbe molto apprezzato.

public override Order Update(Order entity) 
{ 
    dbset.Attach(entity); 
    DataContext.Entry(entity).State = EntityState.Modified; 

    foreach (var orderDetail in entity.OrderDetails) 
    { 
     DataContext.Entry(orderDetail).State = EntityState.Modified; 
    } 

    return entity; 
} 

risposta

4

Questo è common and complex issue e non c'è magia che lo farà per voi. La mia soluzione (e l'unico che funziona in tutti gli scenari) è stato quello di caricare il Order di nuovo nel vostro metodo di aggiornamento e unire le modifiche manualmente:

public override Order Update(Order entity) 
{ 
    // No attach of entity 

    var attached = DataContext.Orders.Include(o => o.OrderDetails).SingleOrDefault(...); 
    if (attached == null) ... 

    // Merge changes from entity to attached - if you change any property 
    // it will be marked as modified automatically 

    foreach (var detail in attached.OrderDetails.ToList()) 
    { 
     // ToList is necessary because you will remove details from the collection 

     // if detail exists in entity check if it must be updated and set its state 

     // if detail doesn't exists in entity remove if from collection - if it is \ 
     // aggregation (detail cannot exists without Order) you must also delete it 
     // from context to ensure it will be deleted from the database 
    } 

    foreach (var detail in entity.OrderDetails) 
    { 
     // if it doesn't exists in attached create new detail instance, 
     // fill it from detail in entity and add it to attached entity - 
     //you must not use the same instance you got from the entity 
    } 

    DataContext.SaveChanges(); 

    return entity; 
} 

Non ci può essere anche necessario verificare manualmente timestamp se li usate.

Lo scenario alternativo è quello che hai descritto con 0 utilizzato per i nuovi dettagli e l'ID negativo per i dettagli cancellati, ma questa è la logica che deve essere eseguita sul client. Funziona anche solo in alcuni casi.

+0

Ottima risposta. Grazie per aver dedicato del tempo! –

+0

Non pensate di avere un'idea del motivo per cui il team EF ha deciso di non perseguire lo scenario di allegare grafici di entità e renderlo un po 'più automatico? Sto pensando che potrebbe essere dovuto a non voler consentire al client di aggiornare, ad esempio Prodotto in un ordine - OrderItem - Scenario del prodotto. –

+0

Più penso a questo problema più credo che l'automazione completa non sia possibile o affidabile (l'affidabilità è esattamente ciò che descrivi - l'aggiornamento automatico potrebbe modificare le entità che non vuoi modificare). –

Problemi correlati