Entity Framework
Caricamento delle entità correlate
Ricerca…
Osservazioni
Se i modelli sono correlati correttamente, puoi caricare facilmente i dati correlati utilizzando EntityFramework. Hai tre opzioni tra cui scegliere: caricamento lazy , caricamento ansioso e caricamento esplicito .
Modelli utilizzati negli esempi:
public class Company
{
public int Id { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
// Navigation properties
public virtual Person Founder { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int CountryId { get; set; }
public int CityId { get; set; }
public string Street { get; set; }
// Navigation properties
public virtual Company Company { get; set; }
public virtual Country Country { get; set; }
public virtual City City { get; set; }
}
Caricamento lento
Il caricamento lento è abilitato per impostazione predefinita. Il caricamento lento si ottiene creando classi proxy derivate e ignorando le proprietà di navigazione virtuale. Il caricamento lento si verifica quando si accede alla proprietà per la prima volta.
int companyId = ...;
Company company = context.Companies
.First(m => m.Id == companyId);
Person founder = company.Founder; // Founder is loaded
foreach (Address address in company.Addresses)
{
// Address details are loaded one by one.
}
Per disattivare il caricamento Lazy per proprietà di navigazione specifiche, rimuovi semplicemente la parola chiave virtuale dalla dichiarazione di proprietà:
public Person Founder { get; set; } // "virtual" keyword has been removed
Se si desidera disattivare completamente il caricamento Lazy, è necessario modificare la configurazione, ad esempio, con il costruttore di Context :
public class MyContext : DbContext
{
public MyContext(): base("Name=ConnectionString")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Nota: ricordarsi di disattivare il caricamento Lazy se si utilizza la serializzazione. Poiché i serializzatori accedono a tutte le proprietà, le caricherete tutte dal database. Inoltre, puoi eseguire il loop tra le proprietà di navigazione.
Carico eccessivo
Il caricamento di Eager ti consente di caricare tutte le entità necessarie contemporaneamente. Se preferisci che tutte le tue entità lavorino in una chiamata al database, allora il caricamento Eager è la strada da percorrere. Ti consente anche di caricare più livelli.
Sono disponibili due opzioni per caricare entità correlate, è possibile scegliere tra overload fortemente tipizzati o stringhe del metodo Include .
Fortemente tipizzato
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include(m => m.Founder)
.Include(m => m.Addresses)
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include(m => m.Addresses.Select(a => a.Country));
.Include(m => m.Addresses.Select(a => a.City))
.Take(5).ToList();
Questo metodo è disponibile da Entity Framework 4.1. Assicurati di avere il riferimento using System.Data.Entity;
impostato.
Sovraccarico di stringa
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include("Founder")
.Include("Addresses")
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include("Addresses.Country");
.Include("Addresses.City"))
.Take(5).ToList();
Caricamento esplicito
Dopo aver disattivato il caricamento Lazy, è possibile caricare le entità caricando in modo esplicito il metodo Load per le voci. Il riferimento viene utilizzato per caricare singole proprietà di navigazione, mentre Collection viene utilizzato per ottenere le raccolte.
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference(m => m.Founder).Load();
// Load addresses
context.Entry(company).Collection(m => m.Addresses).Load();
Poiché è in caricamento Eager , puoi utilizzare gli overload dei metodi precedenti per caricare entiteis in base al loro nome:
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference("Founder").Load();
// Load addresses
context.Entry(company).Collection("Addresses").Load();
Filtro relativo alle entità.
Usando il metodo Query possiamo filtrare le entità correlate caricate:
Company company = context.Companies.FirstOrDefault();
// Load addresses which are in Baku
context.Entry(company)
.Collection(m => m.Addresses)
.Query()
.Where(a => a.City.Name == "Baku")
.Load();
Query di proiezione
Se uno ha bisogno di dati correlati in un tipo denormalizzato, o per esempio solo un sottoinsieme di colonne, si possono usare le query di proiezione. Se non vi è alcun motivo per utilizzare un tipo extra, esiste la possibilità di unire i valori in un tipo anonimo .
var dbContext = new MyDbContext();
var denormalizedType = from company in dbContext.Company
where company.Name == "MyFavoriteCompany"
join founder in dbContext.Founder
on company.FounderId equals founder.Id
select new
{
CompanyName = company.Name,
CompanyId = company.Id,
FounderName = founder.Name,
FounderId = founder.Id
};
O con la sintassi delle query:
var dbContext = new MyDbContext();
var denormalizedType = dbContext.Company
.Join(dbContext.Founder,
c => c.FounderId,
f => f.Id ,
(c, f) => new
{
CompanyName = c.Name,
CompanyId = c.Id,
FounderName = f.Name,
FounderId = f.Id
})
.Select(cf => cf);