Entity Framework / .Net 4.0: POCO e salvataggio di molte relazioni uno a uno
-
06-07-2019 - |
Domanda
Come devo impostare una proprietà in modo tale che quando uso SaveChanges, la relazione molti-a-uno viene salvata e non ottengo l'istruzione: INSERT in conflitto con il vincolo FOREIGN KEY ...
Abbastanza semplice, ho un annuncio e un tipo di annuncio in cui ci sono molti annunci per un tipo di annuncio. C'è una proprietà nell'annuncio:
public class Ad
{
public Int32 AdTypeId { get; set; }
public virtual AdType AdType { get; set; }
}
Per coprire questa relazione.
Quando faccio questo:
someAd.AdType = someAdType;
La proprietà è impostata correttamente, ma AdTypeId non lo è. Non preoccuparti, dato che suppongo che sarebbe giusto salvare.
context.SaveChanges();
A questo punto il problema sta provando a salvare il valore 0 nella colonna AdTypeId (causando un problema di chiave esterna) invece di utilizzare l'oggetto AdType assegnato alla proprietà per capire cosa dovrebbe inserire nella colonna AdTypeId.
Cose che conosco:
- A questo punto someAdType è persistente / ha un ID.
- La proprietà AdType è impostata correttamente.
- AdTypeId è 0.
- Esiste una relazione di chiave esterna nel database.
- AdTypeId è una chiave primaria.
- Ho caricato differito / pigro impostato su true
Non ho davvero provato a modificare AdType poiché è impostato per consentire il caricamento lento.
Soluzione
Ok sembra che sto usando il non proxy (Creato quella parola ... Yah) " Tracking delle modifiche basato su istantanea " approccio, il sistema non ha idea reale che sia cambiato.
In questo esempio, il cliente è puro Tipo POCO. A differenza di EntityObject o Entità basate su IPOCO, apportando modifiche all'entità non automaticamente mantenere sincronizzato il gestore dello stato perché non c'è notifica automatica tra le tue pure entità POCO e il Entity Framework. Pertanto, su interrogando il gestore dello stato, pensa che è lo stato dell'oggetto cliente Invariato anche se lo abbiamo fatto fatto esplicitamente una modifica a uno dei proprietà sull'entità.
Quindi, per essere sicuro di sapere se c'è stato un cambiamento, devo usare opzione AcceptAllChangesAfterSave con il metodo SaveChanges.
context.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);
E funziona. Spero di capirlo correttamente ...