如何在Linq查询中同时加载Teachers多子实体?重复加载及SQL生成疑问
问题1:如何在单次查询中同时包含这两个子实体
你现有写法本身就已经实现了该需求,EF6会把多个Include指定的导航路径合并到单次查询中返回。如果想要代码可读性更高,也可以按导航层级拆分编写,和你现有写法逻辑完全等价:
var x = context.Student .Include(d => d.Class.Select(di => di.Teachers.Select(i => i.Subjects))) .Include(d => d.Class.Select(di => di.Teachers.Select(di => di.Marks))) .FirstOrDefault();
注:EF6 没有EF Core的ThenInclude语法,多级导航加载只能用Select嵌套的写法。
问题2:上述查询执行时,Teachers实体会被重复加载两次吗
不会。EF上下文内置了身份映射机制,同一个主键值的实体,在同一个上下文实例中只会被实例化一次。哪怕最终SQL返回的结果集里有多条重复的Teachers字段数据,EF也会自动做去重处理,内存中只会保留一份Teachers实体对象,不会出现重复加载的问题。
问题3:两次Include了Class相关路径,最终生成的SQL会不会对Class表执行2次Join操作
不会。EF6的SQL生成器会自动识别重复的导航路径前缀做合并优化,你两个Include共同的Student->Class->Teachers路径只会生成一次JOIN逻辑,最终SQL只会关联Class表、Teachers表各一次,再分别关联Subjects和Marks表,不会重复关联Class表。
如果需要确认生成的SQL逻辑,可以在查询前加一行代码打印生成的SQL:
context.Database.Log = sql => Debug.WriteLine(sql);
内容的提问来源于stack exchange,提问作者GANI
相关产品推荐
相关产品推荐

