EF Core使用Include/ThenInclude遇警告,AsSplitQuery致数据异常求助
解决方案
方案1:显式指定单查询模式抑制警告
如果当前查询性能符合预期,无需拆分查询,可以显式设置QuerySplittingBehavior.SingleQuery消除警告,EF会沿用默认的单查询逻辑,同时不再弹出性能提示。
代码示例:
var notes = _context.Fragrances .Where(f => f.FragranceId == fragranceId) .Include(f => f.Notes! .OrderBy(r => Guid.NewGuid()) .Take(2)) .ThenInclude(n => n.Fragrances! .Where(f => f.FragranceId != fragranceId) .OrderBy(r => Guid.NewGuid()) .Take(2)) .AsSingleQuery() // 显式指定单查询模式 .First().Notes;
方案2:使用投影查询(推荐)
投影查询直接构造需要返回的DTO结构,无需依赖Include加载完整实体,既能避免多集合导航的警告,还能减少数据传输量,性能更优。
先定义匹配响应结构的DTO类:
public class NoteDto { public string Name { get; set; } = null!; public List<FragranceDto> Fragrances { get; set; } = new(); } public class FragranceDto { public string FullName => $"{Brand} {Name}"; public string Brand { get; set; } = null!; public string Name { get; set; } = null!; public string Gender { get; set; } = null!; }
再编写投影查询:
var result = _context.Fragrances .Where(f => f.FragranceId == fragranceId) .SelectMany(f => f.Notes! .OrderBy(r => Guid.NewGuid()) .Take(2) .Select(n => new NoteDto { Name = n.Name, Fragrances = n.Fragrances! .Where(fg => fg.FragranceId != fragranceId) .OrderBy(r => Guid.NewGuid()) .Take(2) .Select(fg => new FragranceDto { Brand = fg.Brand, Name = fg.Name, Gender = fg.Gender }) .ToList() })) .ToList();
这种方式直接从数据库获取所需字段,无需加载完整的Fragrance和Note实体,彻底规避多集合导航的警告问题。
方案3:拆分查询为多个步骤
先获取目标香水的2个随机香调,再逐个查询每个香调对应的随机香水,避免一次性加载多层集合导致的逻辑冲突。
代码示例:
// 第一步:获取目标香水的2个随机香调 var targetNotes = _context.FragranceNote .Where(fn => fn.FragranceId == fragranceId) .OrderBy(r => Guid.NewGuid()) .Take(2) .Select(fn => fn.Note) .ToList(); // 第二步:为每个香调获取2个排除目标香水的随机香水 var result = targetNotes.Select(n => new NoteDto { Name = n.Name, Fragrances = _context.FragranceNote .Where(fn => fn.NoteId == n.NoteId && fn.FragranceId != fragranceId) .OrderBy(r => Guid.NewGuid()) .Take(2) .Select(fn => new FragranceDto { Brand = fn.Fragrance.Brand, Name = fn.Fragrance.Name, Gender = fn.Fragrance.Gender }) .ToList() }).ToList();
这种方式拆分了数据库查询,逻辑更清晰,也不会触发多集合导航的警告,适合对数据加载控制更精细的场景。
内容的提问来源于stack exchange,提问作者Cosmin Pascan
相关产品推荐
相关产品推荐

