8

in ASP .NET MVC 3 con Entity Framework, ho un oggetto di dominio che ha una proprietà di navigazione fa riferimento a un altro oggetto, come segue:Come aggiornare le proprietà di navigazione di un'entità in Entity Framework

public class Person 
{ 
    public String Name {get;set;} 

    public Guid CompanyID{get;set;} 

    [ForeignKey(CompanyID)] 
    public virtual CompanyType Company{ get; set; } 
} 

Quando creo un'istanza di Person e prova ad aggiungerla al database, il DBContext mantiene una cache di questa entità 'Person' e la invia al database. Quindi, più avanti nella vita della stessa istanza di contesto, quando provo ad accedere a questa entità, il campo Società è sempre nullo poiché la proprietà di navigazione non è mai stata aggiornata.

C'è un modo per aggiornare la proprietà di navigazione con ciò che esiste nel database?

Il caricamento lento è attivato.

risposta

11

Se lazy loading è attivato e si desidera caricare la proprietà di navigazione con caricamento pigro è necessario creare un proxy di un nuovo Person, non un'istanza con new, in questo modo:

using (var context = new MyDbContext()) 
{ 
    var person = context.People.Create(); // creates a lazy loading proxy 
    person.CompanyID = 123; 
    context.People.Add(person); 
    context.SaveChanges(); 

    var company = person.Company; // lazy loading query happens here 
} 

Senza caricamento pigro è possibile utilizzare il caricamento esplicito:

using (var context = new MyDbContext()) 
{ 
    var person = new Person(); 
    person.CompanyID = 123; 
    context.People.Add(person); 
    context.SaveChanges(); 

    context.Entry(person).Reference(p => p.Company).Load(); // explicit loading 

    var company = person.Company; // no query anymore, Company is already loaded 
} 
+0

Ciò richiede che il programma carichi esplicitamente ogni proprietà di navigazione esistente. C'è un modo per implementare qualcosa di più basilare, per ricaricare tutte le proprietà di navigazione per qualsiasi voce di entità? Ho provato la funzione Reload per DbEntityEntry ma non sembra funzionare. – daniely

+0

@daniely: No, non è possibile. L'unico modo con un singolo rountrip DB sarebbe quello di utilizzare il caricamento ansioso con più 'Includi' per caricare tutte le proprietà di navigazione. Ma questo dovrebbe caricare anche l'entità genitore e devi scrivere manualmente 'Include's per tutte le proprietà di navigazione. – Slauma

+0

@Slauma Quando si utilizza context.People.Include (p => p.NavProp1) .Include (p => p.NavProp2) Posso caricare a catena diverse proprietà di navigazione, creando un singolo hit nel DB. Esiste un modo simile per caricare diverse proprietà di navigazione con context.Entry (person) .Reference (...)? Non riesco a capire un modo per specificare tutte le proprietà del navigatore, quindi posso chiamare solo Load() una volta. –