如何用LINQ方法语法合并三表查询(需保留Except())
合并包含Except()的LINQ查询以避免重复访问Table1
你可以将两次查询合并为一个,通过把Except的逻辑作为子查询嵌入到主查询中,这样就能避免重复访问Table1,同时严格遵循方法语法并保留Except()方法。
合并后的代码有两种实现方式,都能满足需求:
方式一:直接整合过滤逻辑(方法语法全程连贯)
List<RTableModel> result = dbContext.Table1 // 关联Table3 .Join(dbContext.Table3, t1 => t1.BID, t3 => t3.BID, (t1, t3) => t1) // 应用Table1的初始筛选条件 .Where(t1 => t1.ID >= 5 && t1.TID == 1 && t1.SID == rModel.SID) // 用Except等价逻辑过滤掉Table2中存在的ID .Where(t1 => !dbContext.Table2.Select(t2 => t2.ID).Contains(t1.ID)) // 投影生成目标模型 .Select(t1 => new RTableModel { ID = t1.ID, SCode = t1.SCode, time = t1.time.ToString(), // 补充其他需要映射的属性 }) .ToList();
方式二:保留显式Except()方法调用
// 定义Except子查询(保持IQueryable,不提前执行ToList) var validIds = dbContext.Table1 .Where(x => x.ID >= 5 && x.TID == 1 && x.SID == rModel.SID) .Select(s => s.ID) .Except(dbContext.Table2.Select(s => s.ID)); // 主查询关联Table3并筛选符合条件的ID List<RTableModel> result = dbContext.Table1 .Join(dbContext.Table3, t1 => t1.BID, t3 => t3.BID, (t1, t3) => t1) .Where(t1 => validIds.Contains(t1.ID)) .Select(t1 => new RTableModel { ID = t1.ID, SCode = t1.SCode, time = t1.time.ToString(), // 补充其他需要映射的属性 }) .ToList();
核心说明
- 两种方式都只会生成单次数据库查询,不会重复访问
Table1:方式一将Except逻辑转化为等价的!Contains过滤;方式二通过延迟执行的IQueryable子查询,让EF Core自动将整个逻辑合并为一条SQL。 - 严格遵循了方法语法要求,且方式二保留了
Except()方法的显式调用,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Rushikesh Chaudhari
相关产品推荐
相关产品推荐

