EF Core:如何通过多对多关系查询单个公司的唯一用户?
解决EF Core中不使用Include获取公司下唯一用户的查询问题
嘿,我懂你这种LINQ基础薄弱导致EF Core卡壳的感觉!刚好你给出的SQL逻辑很清晰,咱们直接把它转换成对应的EF Core查询,而且完全不用Include——毕竟Include是用来加载导航属性的,这里用显式关联更贴合你的需求。
首先,先明确你的SQL逻辑:关联公司、组、组用户关联表、用户表,过滤指定公司ID,然后取出唯一的用户信息。下面给你两种常用的写法:
1. 查询表达式(Query Syntax)写法
这种写法和SQL的结构最像,容易理解:
var uniqueUsers = (from company in dbContext.Companies join group in dbContext.Groups on company.Id equals group.CompanyId join groupAppUser in dbContext.GroupAppUsers on group.Id equals groupAppUser.GroupId join appUser in dbContext.AppUsers on groupAppUser.AppUserId equals appUser.Id where company.Id == 40 select new { AppUserId = groupAppUser.AppUserId, appUser.Name, appUser.Id }).Distinct();
2. 方法链(Method Syntax)写法
如果你习惯用链式调用,这种写法更紧凑:
var uniqueUsers = dbContext.Companies .Where(c => c.Id == 40) .Join(dbContext.Groups, company => company.Id, group => group.CompanyId, (company, group) => group) .Join(dbContext.GroupAppUsers, group => group.Id, groupAppUser => groupAppUser.GroupId, (group, groupAppUser) => groupAppUser) .Join(dbContext.AppUsers, groupAppUser => groupAppUser.AppUserId, appUser => appUser.Id, (groupAppUser, appUser) => new { groupAppUser.AppUserId, appUser.Name, appUser.Id }) .Distinct();
几个关键说明:
- 为什么不用Include?:
Include是用来加载实体的导航属性(比如Company.Groups),但这里我们需要的是跨多表关联后筛选去重,直接用Join能精准控制要查询的字段和关联逻辑,比Include更灵活,也不会加载多余的数据。 - Distinct的作用:这里的
Distinct会基于我们匿名类型的所有属性进行去重(因为C#匿名类型自动实现了基于属性的相等比较),刚好对应SQL里的DISTINCT。 - 返回实体或DTO:如果不想用匿名类型,建议定义一个DTO类(比如
UserSummaryDto),然后在select里实例化这个DTO,这样后续使用起来更方便,避免匿名类型的局限性。
举个DTO的例子:
public class UserSummaryDto { public int AppUserId { get; set; } public string Name { get; set; } public int Id { get; set; } } // 然后查询里改成: select new UserSummaryDto { AppUserId = groupAppUser.AppUserId, Name = appUser.Name, Id = appUser.Id }
这样写出来的EF Core查询,最终生成的SQL和你给出的几乎一致,完全满足你的需求!
内容的提问来源于stack exchange,提问作者Raphael Lima
相关产品推荐
相关产品推荐

