Entity Framework
Ładowanie powiązanych podmiotów
Szukaj…
Uwagi
Jeśli modele są poprawnie powiązane, możesz łatwo załadować powiązane dane za pomocą EntityFramework. Masz trzy opcje do wyboru: leniwe ładowanie , chętne ładowanie i jawne ładowanie .
Modele użyte w przykładach:
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; }
}
Powolne ładowanie
Leniwe ładowanie jest domyślnie włączone. Leniwe ładowanie odbywa się poprzez tworzenie pochodnych klas proxy i zastępowanie wirtualnych właściwości nawigacyjnych. Leniwe ładowanie ma miejsce, gdy właściwość jest otwierana po raz pierwszy.
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.
}
Aby wyłączyć ładowanie Lazy dla określonych właściwości nawigacji, po prostu usuń wirtualne słowo kluczowe z deklaracji właściwości:
public Person Founder { get; set; } // "virtual" keyword has been removed
Jeśli chcesz całkowicie wyłączyć ładowanie Lazy, musisz zmienić konfigurację, na przykład w Konstruktorze kontekstu :
public class MyContext : DbContext
{
public MyContext(): base("Name=ConnectionString")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Uwaga: pamiętaj, aby wyłączyć ładowanie Lazy, jeśli używasz serializacji. Ponieważ serializatory mają dostęp do każdej właściwości, którą zamierzasz załadować wszystkie z bazy danych. Dodatkowo możesz uruchomić pętlę między właściwościami nawigacji.
Chętnie ładuję
Chętne ładowanie pozwala załadować wszystkie potrzebne jednostki na raz. Jeśli wolisz, aby wszystkie twoje jednostki pracowały w jednym wywołaniu bazy danych, to chętny jest ładowanie . Umożliwia także ładowanie wielu poziomów.
Masz dwie opcje ładowania jednostek powiązanych, możesz wybrać przeciążenie silnie typowane lub ciąg znaków metody Include .
Mocno napisane.
// 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();
Ta metoda jest dostępna od Entity Framework 4.1. Upewnij się, że masz referencję using System.Data.Entity;
zestaw.
Przeciążenie łańcucha.
// 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();
Jawne ładowanie
Po wyłączeniu Lazy ładowania można leniwie ładować jednostki, jawnie wywołując metodę Load dla wpisów. Odwołanie służy do ładowania pojedynczych właściwości nawigacji, natomiast Kolekcja służy do pobierania kolekcji.
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();
Podobnie jak w przypadku Chętnego ładowania , możesz użyć przeciążeń powyższych metod, aby załadować entitei według ich nazw:
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference("Founder").Load();
// Load addresses
context.Entry(company).Collection("Addresses").Load();
Filtruj powiązane podmioty.
Za pomocą metody Query możemy filtrować załadowane powiązane podmioty:
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();
Zapytania projekcyjne
Jeśli potrzebne są powiązane dane w zdenormalizowanym typie lub np. Tylko podzbiór kolumn, można użyć zapytań projekcyjnych. Jeśli nie ma powodu, aby używać dodatkowego typu, istnieje możliwość połączenia wartości w anonimowy typ .
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
};
Lub ze składnią zapytania:
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);