L'sia interrogazione stanno recuperando i dati relativi solo prima query utilizzando Eager Loading (e sì eager loading è ottenuta con l'uso del metodo di Include
come avete indovinato) e la seconda query utilizzando Lazy loading che è per impostazione predefinita. Ma poiché la query restituirà solo EmailAddresses
a causa delle operazioni Select()
e SelectMany()
, il metodo Include()
non modifica il comportamento. Per vedere quandoInclude()
metodo è la materia nel tuo esempio leggere le seguenti righe che io lo dimostrerò in un esempio:
conoscere alcune differenze tra questi due tipi di entità correlate di carico eager loading è in genere più efficiente quando hai bisogno dei dati relativi per tutte le righe recuperate della tabella primaria. E anche quando i rapporti sononon troppo, carico eccessivo sarà una buona pratica per ridurre ulteriori query sul server. Ma quando sai che non avrai bisogno di una proprietà istantanea, allora il caricamento lento potrebbe essere una buona scelta. E anche il carico impaziente è una buona scelta in una situazione in cui il tuo contesto db viene eliminato e il caricamento lento non può più avvenire. Per dimostrare che uno è pigro Caricamento e uno è desideroso Caricamento considerare il seguente codice:
public List<Person> GetEmailAddresses()
{
using (yourEntities awlt = new yourEntities())
{
var query = awlt.People
.Where(p => p.LastName.Equals(lastName));
return query.ToList();
}
}
Dopo aver chiamato questo metodo, non è possibile caricare l'entità correlata pigramente perché il db è disposto. Per dimostrare provare questo:
var query = GetEmailAddresses();
foreach (var item in query.SelectMany(a => a.EmailAddresses).Select(a => a.EmailAddress1))
{
MessageBox.Show(item);
}
Ed otterrete questo errore:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Ma se si cambia la GetEmailAddresses
di utilizzare Eager Loading in questo modo:
public List<Person> GetEmailAddresses()
{
using (yourEntities awlt = new yourEntities())
{
var query = awlt.People.Include("EmailAddresses")
.Where(p => p.LastName.Equals(lastName));
return query.ToList();
}
}
Poi il codice qui sotto dovrebbe funzionare bene:
var query = GetEmailAddresses();
foreach (var item in query.SelectMany(a => a.EmailAddresses).Select(a => a.EmailAddress1))
{
MessageBox.Show(item);
}
Quindi, in una situazione in cui il contesto db sarebbe stato smaltito, il Eager Loading sarebbe una scelta migliore.
fonte
2016-05-04 11:42:39
Quale versione di EF? Nelle versioni precedenti a 7, entrambe funzioneranno allo stesso modo. L'unica differenza sarebbe restituire la raccolta 'People' senza altre query. Quindi 'EmailAddresses' verrebbe compilato solo se invocato (pigro) –
@RoyalBg: utilizzo la versione 6.1.3, potresti spiegare di più la differenza? –
Diciamo che è necessario serializzare il risultato della query 'awlt.People'. Senza includere non riceverai gli indirizzi email. Ma se li invochi prima della serializzazione (in questo caso "Seleziona"), li riceverai, quindi non hai bisogno di includere. Nella versione 7 hai sempre bisogno di includere (o così è stato un mese fa) –