Dychtivá načítání souvisejících dat
Včasné načítání
Metodu Include
můžete použít k určení souvisejících dat, která se mají zahrnout do výsledků dotazu. V následujícím příkladu budou mít blogy, které se vrátí ve výsledcích, jejich Posts
vlastnost naplněna souvisejícími příspěvky.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
}
Tip
Entity Framework Core automaticky opraví navigační vlastnosti na všechny ostatní entity, které byly dříve načteny do kontextové instance. Takže i když explicitně nezahrnete data pro navigační vlastnost, může být tato vlastnost stále naplněna, pokud byly dříve načteny některé nebo všechny související entity.
Do jednoho dotazu můžete zahrnout související data z více relací.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.Include(blog => blog.Owner)
.ToList();
}
Upozornění
Při načítání navigace v kolekci v jednom dotazu může dojít k problémům s výkonem. Další informace najdete v tématu Jednoúčelové a rozdělené dotazy.
Zahrnutí více úrovní
Pomocí metody můžete přejít k podrobnostem relací a zahrnout více úrovní souvisejících dat ThenInclude
. Následující příklad načte všechny blogy, související příspěvky a autora každého příspěvku.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
}
Můžete zřetězí více volání ThenInclude
, abyste mohli pokračovat, včetně dalších úrovní souvisejících dat.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
}
Všechna volání, která mají zahrnovat související data z více úrovní a více kořenových certifikátů ve stejném dotazu, můžete zkombinovat.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Include(blog => blog.Owner)
.ThenInclude(owner => owner.Photo)
.ToList();
}
Můžete chtít zahrnout více souvisejících entit pro jednu z zahrnutých entit. Například při dotazování Blogs
, zahrnete Posts
a pak chcete zahrnout jak the Author
, tak Tags
i z Posts
. Pokud chcete zahrnout obojí, musíte zadat každou cestu k zahrnutí, která začíná v kořenovém adresáři. Příklad: Blog -> Posts -> Author
a Blog -> Posts -> Tags
. Neznamená to, že získáte redundantní spojení; ve většině případů EF zkombinuje spojení při generování SQL.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToList();
}
Tip
Pomocí jedné Include
metody můžete také načíst více navigačních panelů. To je možné pro navigaci "řetězy", které jsou všechny odkazy, nebo když končí jedinou kolekcí.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Owner.AuthoredPosts)
.ThenInclude(post => post.Blog.Owner.Photo)
.ToList();
}
Filtrované zahrnutí
Když použijete možnost Zahrnout pro načtení souvisejících dat, můžete do zahrnuté navigace v kolekci přidat určité výčtové operace, které umožňují filtrování a řazení výsledků.
Mezi podporované operace patří: Where
, OrderBy
, OrderByDescending
, ThenBy
, ThenByDescending
, Skip
, a Take
.
Tyto operace by se měly použít na navigaci kolekce v lambda předané metodě Include, jak je znázorněno v následujícím příkladu:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(
blog => blog.Posts
.Where(post => post.BlogId == 1)
.OrderByDescending(post => post.Title)
.Take(5))
.ToList();
}
Každá zahrnutá navigace umožňuje pouze jednu jedinečnou sadu operací filtru. V případech, kdy se pro danou navigaci v kolekci použije více operací zahrnutí (blog.Posts
v následujících příkladech), je možné operace filtru zadat pouze na jednom z nich:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
.ToList();
}
Místo toho je možné použít identické operace pro každou navigaci, která je zahrnuta vícekrát:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
.ToList();
}
Upozornění
V případě sledovacích dotazů můžou být výsledky filtrovaného zahrnutí neočekávané kvůli opravě navigace. Všechny relevantní entity, na které byly dotazovány dříve a které byly uloženy v nástroji Change Tracker, se zobrazí ve výsledcích dotazu Filtered Include, i když nesplňují požadavky filtru. Zvažte použití NoTracking
dotazů nebo opětovné vytvoření dbContext při použití filtered Include v těchto situacích.
Příklad:
var orders = context.Orders.Where(o => o.Id > 1000).ToList();
// customer entities will have references to all orders where Id > 1000, rather than > 5000
var filtered = context.Customers.Include(c => c.Orders.Where(o => o.Id > 5000)).ToList();
Poznámka
V případě sledovacíchdotazůch To znamená, že EF Core se nepokusí znovu načíst své hodnoty pomocí explicitního načítání nebo opožděného načítání, i když některé prvky můžou stále chybět.
Zahrnout do odvozených typů
Můžete zahrnout související data z navigace definované pouze u odvozeného typu pomocí Include
a ThenInclude
.
S ohledem na následující model:
public class SchoolContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<School> Schools { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<School>().HasMany(s => s.Students).WithOne(s => s.School);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Student : Person
{
public School School { get; set; }
}
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public List<Student> Students { get; set; }
}
School
Obsah navigace všech Lidé, kteří jsou studenti, se dají dychtivě načíst pomocí mnoha vzorů:
Použití přetypování
context.People.Include(person => ((Student)person).School).ToList()
Použití
as
operátorucontext.People.Include(person => (person as Student).School).ToList()
Použití přetížení
Include
, které přebírá parametr typustring
context.People.Include("School").ToList()
Konfigurace modelu pro automatickou navigaci
Navigaci v modelu můžete nakonfigurovat tak, aby byla zahrnuta při každém načtení entity z databáze pomocí AutoInclude
metody. Má stejný účinek jako zadání Include
navigace v každém dotazu, ve kterém je typ entity vrácen ve výsledcích. Následující příklad ukazuje, jak nakonfigurovat navigaci tak, aby byla automaticky zahrnuta.
modelBuilder.Entity<Theme>().Navigation(e => e.ColorScheme).AutoInclude();
Po výše uvedené konfiguraci se spuštěním dotazu, jako je níže, načte ColorScheme
navigaci pro všechny motivy ve výsledcích.
using (var context = new BloggingContext())
{
var themes = context.Themes.ToList();
}
Tato konfigurace se použije pro každou entitu vrácenou ve výsledku bez ohledu na to, jak se ve výsledcích objevila. To znamená, že pokud je entita ve výsledku kvůli použití navigace, pomocí Include
jiného typu entity nebo konfigurace automatického zahrnutí, načte všechny automaticky zahrnuté navigace. Stejné pravidlo se vztahuje na navigace nakonfigurované jako automaticky zahrnuté u odvozeného typu entity.
Pokud u konkrétního dotazu nechcete načíst související data prostřednictvím navigace, která je nakonfigurovaná na úrovni modelu tak, aby byla automaticky zahrnuta, můžete v dotazu použít IgnoreAutoIncludes
metodu. Pomocí této metody se zastaví načítání všech navigačních panelů nakonfigurovaných jako automatické zahrnutí uživatelem. Spuštění dotazu podobného níže vrátí všechny motivy z databáze, ale nenačte ColorScheme
se, i když je nakonfigurovaná jako automatická navigace.
using (var context = new BloggingContext())
{
var themes = context.Themes.IgnoreAutoIncludes().ToList();
}
Poznámka
Navigace na vlastněné typy jsou také nakonfigurované jako automaticky zahrnuté podle konvence a použití IgnoreAutoIncludes
rozhraní API nezastaví jejich zahrnutí. Budou stále zahrnuty do výsledků dotazu.