将指定SQL查询转换为C# Web API的LINQ语句并解决报错
问题:将SQL的NOT EXISTS查询转为C# Web API的LINQ实现
需要实现的原SQL查询如下,功能是获取Branch表中,不存在于vBranching表(且UserName为xCuttiepies)的Branchname:
SELECT Branchname FROM Branch WHERE NOT EXISTS (SELECT Branchname FROM vBranching WHERE Branch.Branchname = vBranching.Branchname AND UserName = 'xCuttiepies');
尝试的LINQ代码如下,但在Branch == vBranching处报错:无法将bool转换为System.Predicate
var Branch = _dbcontext.Branches.Select(c => c.Branchname).ToList(); var vBranching = _dbcontext.VBranchings.Select(a => a.BranchName).ToList(); var ass = Branch.Where(!Branch.Exists(Branch == vBranching)); return Ok(vBranching);
解决方案
错误原因
Branch.Exists()需要传入判断单元素的委托(Predicate),直接写Branch == vBranching是布尔值,类型不匹配- 逻辑错误:未过滤
vBranching中的UserName条件,也没正确判断分支名称是否存在 - 提前调用
ToList()会把整张表数据加载到内存,效率低下;最后返回的vBranching也不是目标结果
正确实现(两种方式)
方式1:贴近原SQL的NOT EXISTS写法(推荐,EF会生成数据库端执行的高效查询)
var result = _dbcontext.Branches .Where(b => !_dbcontext.VBranchings.Any(v => v.BranchName == b.Branchname && v.UserName == "xCuttiepies")) .Select(b => b.Branchname) .ToList(); return Ok(result);
这种写法EF会生成和原SQL几乎一致的NOT EXISTS语句,所有过滤逻辑在数据库端完成,性能最优。
方式2:先筛选用户关联分支,再判断包含关系
// 先获取该用户对应的所有分支名称 var userRelatedBranches = _dbcontext.VBranchings .Where(v => v.UserName == "xCuttiepies") .Select(v => v.BranchName) .ToList(); // 筛选Branch表中不在该集合内的分支名称 var result = _dbcontext.Branches .Where(b => !userRelatedBranches.Contains(b.Branchname)) .Select(b => b.Branchname) .ToList(); return Ok(result);
内容的提问来源于stack exchange,提问作者xCuttiepie
相关产品推荐
相关产品推荐

