Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ivrig inläsning
Du kan använda Include metoden för att ange relaterade data som ska ingå i frågeresultatet. I följande exempel kommer de bloggar som returneras i resultatet att ha sin Posts egenskap ifylld med relaterade inlägg.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ToListAsync();
}
Tips/Råd
Entity Framework Core korrigerar automatiskt navigeringsegenskaper hos andra entiteter som tidigare lästs in i sammanhangsexemplaret. Så även om du inte uttryckligen inkluderar data för en navigeringsegenskap kan egenskapen fortfarande fyllas i om vissa eller alla relaterade entiteter har lästs in tidigare.
Du kan inkludera relaterade data från flera relationer i en enda fråga.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.Include(blog => blog.Owner)
.ToListAsync();
}
Försiktighet
Ivrig inläsning av en samlingsnavigering i en enda fråga kan orsaka prestandaproblem. För mer information, se Enskilda vs. delade frågor.
Inkludera flera nivåer
Du kan öka detaljnivån genom relationer för att inkludera flera nivåer av relaterade data genom att använda metoden ThenInclude. I följande exempel läses alla bloggar, deras relaterade inlägg och författaren till varje inlägg in.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToListAsync();
}
Du kan kedja flera anrop till ThenInclude för att fortsätta inkludera ytterligare nivåer av relaterad data.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToListAsync();
}
Du kan kombinera alla anrop för att inkludera relaterade data från flera nivåer och flera rötter i samma fråga.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Include(blog => blog.Owner)
.ThenInclude(owner => owner.Photo)
.ToListAsync();
}
Du kanske vill inkludera flera relaterade entiteter för en av de entiteter som ingår. När du till exempel frågar om Blogs, tar du med Posts och vill sedan inkludera både Author och Tags av Posts. Om du vill inkludera båda måste du ange varje inkluderingssökväg som börjar vid roten. Till exempel Blog -> Posts -> Author och Blog -> Posts -> Tags. Det betyder inte att du får redundanta kopplingar. I de flesta fall kombinerar EF kopplingarna när SQL genereras.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToListAsync();
}
Tips/Råd
Du kan också läsa in flera navigeringar med en enda Include metod. Detta är möjligt för navigeringskedjor som alla är referenser, eller när de slutar med en enda samling.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Owner.AuthoredPosts)
.ThenInclude(post => post.Blog.Owner.Photo)
.ToListAsync();
}
Filtrerad inkludering
När du använder Inkludera för att läsa in relaterade data kan du lägga till vissa uppräkningsbara åtgärder i den inkluderade samlingsnavigeringen, vilket möjliggör filtrering och sortering av resultaten.
Åtgärder som stöds är: Where, OrderBy, OrderByDescending, ThenBy, ThenByDescendingoch SkipTake.
Sådana åtgärder bör tillämpas på samlingsnavigeringen i lambda som skickas till metoden Inkludera, som du ser i exemplet nedan:
using (var context = new BloggingContext())
{
var filteredBlogs = await context.Blogs
.Include(
blog => blog.Posts
.Where(post => post.BlogId == 1)
.OrderByDescending(post => post.Title)
.Take(5))
.ToListAsync();
}
Varje inkluderad navigering tillåter endast en unik uppsättning filteråtgärder. I de fall där flera Inkludera-åtgärder används för en viss samlingsnavigering (blog.Posts i exemplen nedan) kan filteråtgärder endast anges på någon av dem:
using (var context = new BloggingContext())
{
var filteredBlogs = await 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))
.ToListAsync();
}
Du kan också använda identiska åtgärder för varje navigering som ingår flera gånger:
using (var context = new BloggingContext())
{
var filteredBlogs = await 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))
.ToListAsync();
}
Försiktighet
Vid frågespårning kan resultatet av Filtrerad Inkludering vara oväntat på grund av navigeringskorrigering. Alla relevanta entiteter som har frågats efter tidigare och har lagrats i Ändringsspåraren finns i resultatet av filtrerad Inkludera-fråga, även om de inte uppfyller filtrets krav. Överväg att använda NoTracking frågor eller återskapa DbContext när du använder Filtrerad Inkludering i dessa situationer.
Exempel:
var orders = await context.Orders.Where(o => o.Id > 1000).ToListAsync();
// customer entities will have references to all orders where Id > 1000, rather than > 5000
var filtered = await context.Customers.Include(c => c.Orders.Where(o => o.Id > 5000)).ToListAsync();
Anmärkning
Vid spårningsfrågor betraktas den navigering som den filtrerade inkluderingen har tillämpats på som inläst. Det innebär att EF Core inte försöker läsa in sina värden på nytt med explicit loading eller lazy loading, även om vissa element fortfarande kan saknas.
Inkludera på härledda typer
Du kan inkludera relaterade data från navigering som endast definierats för en härledd typ med hjälp av Include och ThenInclude.
Med tanke på följande modell:
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 Innehållet i navigeringen för alla personer som är studenter kan ivrigt läsas in med hjälp av många mönster:
Använda cast
context.People.Include(person => ((Student)person).School).ToList()Använda
asoperatörcontext.People.Include(person => (person as Student).School).ToList()Användning av en överlagring av
Includesom accepterar en parameter av typenstringcontext.People.Include("School").ToList()
Modellkonfiguration för automatisk inkludering av navigeringar
Du kan konfigurera en navigering i modellen så att den inkluderas varje gång entiteten läses in från databasen med hjälp av AutoInclude metoden. Den har samma effekt som att ange Include med navigering i varje frågeställning där entitetstyp returneras i resultaten. I följande exempel visas hur du konfigurerar en navigering som ska inkluderas automatiskt.
modelBuilder.Entity<Theme>().Navigation(e => e.ColorScheme).AutoInclude();
Efter att ovanstående har konfigurerats, kommer en fråga liknande den nedan att ladda in ColorScheme-navigeringen för alla teman i resultaten.
using (var context = new BloggingContext())
{
var themes = await context.Themes.ToListAsync();
}
Den här konfigurationen tillämpas på varje entitet som returneras i resultatet oavsett hur den visades i resultatet. Det innebär att om en entitet finns i resultatet på grund av användning av en navigering, med hjälp av Include över en annan entitetstyp eller automatisk inkluderingskonfiguration, kommer alla navigeringar som automatiskt inkluderats för den att läsas in. Samma regel sträcker sig till de navigeringar som konfigurerats som automatiskt inkluderade på härledd typ av entitet.
Om du för en viss fråga inte vill läsa in relaterade data via en navigering, som är konfigurerad på modellnivå som ska inkluderas automatiskt, kan du använda IgnoreAutoIncludes metoden i frågan. Med den här metoden stoppas inläsningen av alla navigeringar som har konfigurerats som automatisk inkludering av användaren. Genom att köra en fråga som den nedan hämtas alla teman från databasen men ColorScheme kommer inte att läsas in trots att det är konfigurerat som automatiskt inkluderad navigering.
using (var context = new BloggingContext())
{
var themes = await context.Themes.IgnoreAutoIncludes().ToListAsync();
}
Anmärkning
Navigeringar till ägda typer konfigureras också som automatiskt inkluderade enligt konvention, och användning av IgnoreAutoIncludes API hindrar dem inte från att inkluderas. De kommer fortfarande att ingå i frågeresultaten.