问题
For a TestType I wanted to include both navigation props Schoolclass and Subject.
I could do a:
.Include(t => t.TestType)
.ThenInclude(x => x.Subject)
but not a:
.Include(t => t.TestType)
.ThenInclude(x => x.Subject)
.ThenInclude(x => x.Schoolclass)
Thus I tried a little trick and that worked:
I included the TestType 2 times...
var test = await context.Tests.Where(t => t.SchoolyearId == schoolyearId)
.Include(t => t.TestType)
.ThenInclude(x => x.Subject)
.Include(t => t.TestType)
.ThenInclude(x => x.Schoolclass)
.AsNoTracking()
.ToListAsync();
Is that the official approach or is there a better one?
UPDATE
public class TestType
{
public TestType()
{
Tests = new HashSet<Test>();
}
public int Id { get; set; }
public string Name { get; set; }
public int Weight { get; set; }
public ISet<Test> Tests { get; set; }
public Schoolyear Schoolyear { get; set; }
public Schoolclass Schoolclass { get; set; }
public Subject Subject { get; set; }
public int SchoolyearId { get; set; }
}
回答1:
the best way is that you write before, With two .Include(t => t.TestType)
var test = await context.Tests.Where(t => t.SchoolyearId == schoolyearId)
.Include(t => t.TestType)
.ThenInclude(x => x.Subject)
.Include(t => t.TestType)
.ThenInclude(x => x.Schoolclass)
.AsNoTracking()
.ToListAsync();
If you see the query result in SQL Profiler, the query is that you pretend, without repeating the include to TestType (only 1 join with that table)
You have another way to do it, but i prefer the before way!
.Include("TestType.Subject")
.Include("TestType.Schoolclass")
回答2:
This approach is the only one that exists in 1.1.0 :)
Better one is little different - do not load all objects in one query (DB will join 4 tables - Tests
, TestType
, Schoolyear
, Schoolclass
), because this may cause unnecessary data growth (when you will have a lot or records in tests
).
If some of your tables (Schoolyear? or even TestType?) contains relatively small amount of records (comparing to "main" Tests
table) - you can load TestTypes.Include(x => x.Subject).Include(x => x.Schoolclass)
first, save them in some list, and then query only Tests
without extra "Include". But as soon as you already have TestType
with all required dependencies in memory - they may be accessed from memory.
Moreover, if some of your tables are changing rarely - use Caching to read them from DB once and re-read when necessary (remove appropriate cache entry in controllers that manage this tables).
回答3:
Why you don't use Include
twice?
var myVar= ((MyContext) _context)
.MasterEntity
.Include(x => x.FirstChild)
.Include(x=>x.FirstChild.FirstGrandChild)
.Include(x=>x.FirstChild.SecondGrandChild)
.Where(x => x.Id== input)
.ToList();
来源:https://stackoverflow.com/questions/40953665/how-to-do-multiple-theninclude-navigation-props-after-one-include