16

Considerare Person e Address classi definite comeIn Entity Framework, perché il caricamento non pigro non funziona per una proprietà di navigazione da uno a zero o uno?

class Person 
{ 
    public int PersonId { get; set; } 
    public virtual Address Address { get; set; } 
} 

class Address 
{ 
    public int PersonId { get; set; } 
    public virtual Person Person { get; set; } 
} 

in cui soltanto alcuni Le persone hanno un indirizzo, ma tutti gli indirizzi avere una persona. Si tratta di un one-to-zero-or-one relationship, quindi configurarlo come

modelBuilder.Entity<Address>() 
    .HasKey(a => a.PersonId) 
    .HasRequired(a => a.Person) 
    .WithOptional(a => a.Address); 

Ora, nel mio codice il seguente approccio (eager loading) funziona perfettamente bene.

var person = context.Person 
    .Include(a => a.Address) 
    .Single(a => a.PersonId == 123); 
var address = person.Address; // address != null (correct) 

Tuttavia, il seguente approccio (caricamento lazy) non lo fa.

var person = context.Person 
    .Single(a => a.PersonId == 123); 
var address = person.Address; // address == null (incorrect) 

Inoltre, ho collegato SQL Profiler e posso vedere che EF non è nemmeno tentando di carico pigri l'indirizzo nel secondo caso - restituisce semplicemente nulla.

Non sono riuscito a trovare alcuna documentazione che indichi che EF non è pigro a caricare le proprietà di navigazione one-to-zero-or-one. È questo di progettazione, è un bug, o sto facendo qualcosa di sbagliato?

Ho testato questo con Entity Framework 5 e Entity Framework 6 Alpha 3 e ottenuto gli stessi risultati.

+1

Funziona per me. Sei sicuro che 'ProxyCreationEnabled' e' LazyLoadingEnabled' siano veri per il contesto? –

risposta

23

Ho pensato questo fuori. Le classi di entità devono essere dichiarate come public e le proprietà public virtual per il caricamento lento al lavoro. Cioè

public class Person 
{ 
    public int PersonId { get; set; } 
    public virtual Address Address { get; set; } 
} 

public class Address 
{ 
    public int PersonId { get; set; } 
    public virtual Person Person { get; set; } 
} 
+0

Mi sono imbattuto in questo problema. Hai trovato qualche documentazione su questo? – ironic

+1

No, sfortunatamente non l'ho fatto. L'ho capito attraverso prove ed errori. – Mike

+0

Questo è piuttosto ovvio a causa del routing proxy dinamico, ma non l'ho notato e ho dovuto cercarlo. Grazie alla tua risposta qui, sta funzionando ora;) – julealgon

1

Un altro punto che potrebbe anche essere la ragione a volte, è se si dimentica di aggiungere il modificatore virtuale alla proprietà di navigazione

0

Se si utilizza Database primo approccio, assicurarsi che la proprietà di Lazy Loading Enabled è Vero. Puoi trovare questa proprietà nelle proprietà del diagramma EDMX.

È inoltre possibile ignorare il comportamento impostando dbcontext.Configuration.LazyLoadingEnabled = true dove DbContext è l'istanza di DbContext.