LINQ使用GroupBy后Include预加载的Titolare字段返回null问题
LINQ添加GroupBy后Titolare字段返回null的问题解答
根本原因
- EF/EF Core中的
Include方法仅在查询最终返回的形状就是被Include的实体类型时生效,一旦中间出现GroupBy、自定义投影这类改变查询返回形状的操作,EF会直接忽略之前定义的所有Include规则。 - 你的代码中
GroupBy执行后,返回结果类型变为IGrouping<TKey, Benefici>,已经不是原始的Benefici实体集合,因此Include定义的Titolare、ComuneDomicilio关联属性不会被EF加载,最终取出的实体中Titolare自然为null。 - 移除GroupBy后查询返回形状始终是Benefici集合,Include可以正常生效,所以Titolare能正常返回值。
解决方案
方案1:小数据量场景,提前加载全量数据到内存再分组
将ToList调用移到GroupBy之前,先把所有符合条件且带关联属性的Benefici实体加载到内存,再做内存分组操作,此时Include不会失效:
var ben = context.Benefici.Include("Titolare").Include("Titolare.ComuneDomicilio") .Where(b => !b.Titolare.SD1_DAT_DECESSO.HasValue) .OrderByDescending(b => b.SDB_DAT_INIZIO) .ToList() // 先加载所有带关联属性的实体到内存 .GroupBy(b => b.SDB_CODDIS) .Select(b => b.First()) .ToList();
注意:如果符合条件的Benefici数据量很大,该方案会占用较多内存,适合数据量较小的场景。
方案2:大数据量场景,分两次查询避免全量加载
先在数据库层面查询每个分组对应的最新Benefici主键,再用主键批量查询带关联属性的实体,性能更优:
// 假设Benefici的主键字段为Id,替换为你实际的主键名 var latestBenIds = context.Benefici .Where(b => !b.Titolare.SD1_DAT_DECESSO.HasValue) .OrderByDescending(b => b.SDB_DAT_INIZIO) .GroupBy(b => b.SDB_CODDIS) .Select(b => b.First().Id) .ToList(); // 用主键查询带关联属性的目标实体 var ben = context.Benefici.Include("Titolare").Include("Titolare.ComuneDomicilio") .Where(b => latestBenIds.Contains(b.Id)) .OrderByDescending(b => b.SDB_DAT_INIZIO) .ToList();
内容的提问来源于stack exchange,提问作者sara
相关产品推荐
相关产品推荐

