如何在LINQ语句中按fournisseur.Id分组并包含无类型/分类的记录?
解决方案
你的问题核心是内连接过滤掉了无关联类型/分类的供应商,且手动join导致重复记录,DistinctBy无法正常工作。以下是两种可行的解决方式:
方式一:利用EF导航属性(推荐)
EF Core的导航属性会自动处理关联查询,无需手动写join,天然支持包含无关联数据的场景,且不会产生重复记录:
var result = _context.Fournisseurs .OrderBy(fournisseur => fournisseur.Nom) .Select(fournisseur => new { fournisseur.Id, fournisseur.Siren, Contacts = fournisseur.Agences.Select(a => a.Contacts), Categories = fournisseur.FournisseurCategories.Select(fc => fc.CategorieId), Types = fournisseur.FournisseurTypeFournisseurs.Select(ft => ft.TypeFournisseurId), fournisseur.Agences, fournisseur.Nom }); return Ok(result);
若需优化性能,可添加Include预加载关联数据(投影查询时EF会自动处理必要的关联加载):
var result = _context.Fournisseurs .Include(f => f.Agences) .Include(f => f.FournisseurCategories) .Include(f => f.FournisseurTypeFournisseurs) .OrderBy(f => f.Nom) .Select(f => new { f.Id, f.Siren, Contacts = f.Agences.Select(a => a.Contacts), Categories = f.FournisseurCategories.Select(fc => fc.CategorieId), Types = f.FournisseurTypeFournisseurs.Select(ft => ft.TypeFournisseurId), f.Agences, f.Nom });
方式二:左外连接+分组
如果必须手动写join,需将内连接改为左外连接,通过join ... into创建分组,避免重复记录:
var result = from fournisseur in _context.Fournisseurs // 左连接类型表,将匹配结果分组 join type in _context.FournisseurTypeFournisseurs on fournisseur.Id equals type.FournisseurId into typesGroup // 左连接分类表,将匹配结果分组 join categorie in _context.FournisseurCategories on fournisseur.Id equals categorie.FournisseurId into categoriesGroup orderby fournisseur.Nom select new { fournisseur.Id, fournisseur.Siren, Contacts = fournisseur.Agences.Select(a => a.Contacts), Categories = categoriesGroup.Select(c => c.CategorieId), Types = typesGroup.Select(t => t.TypeFournisseurId), fournisseur.Agences, fournisseur.Nom }; return Ok(result);
原代码问题说明
- 内连接过滤数据:你使用的
join是内连接,只有同时存在关联类型和分类的供应商才会被保留,无关联的会被过滤。 DistinctBy失效原因:手动join后,一个供应商对应多个类型/分类会生成多条重复记录,若在IQueryable上调用DistinctBy,部分EF Core版本无法将其转换为SQL;若先ToList()在内存中执行则可行,但会影响查询性能。
内容的提问来源于stack exchange,提问作者resr
相关产品推荐
相关产品推荐

