How to do Multiple ThenInclude navigation props after One Include

吃可爱长大的小学妹 提交于 2019-12-10 14:25:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!