如何在LINQ中实现PostgreSQL嵌套CASE WHEN THEN END逻辑?
解决PostgreSQL嵌套CASE WHEN转LINQ的问题
先还原你的PostgreSQL原查询逻辑(模拟常见写法)
SELECT n.id, CASE WHEN EXISTS (SELECT 1 FROM license l WHERE l.node_id = n.id AND l.type = 'Type1') AND EXISTS (SELECT 1 FROM license l WHERE l.node_id = n.id AND l.type = 'Type2') THEN 'Status1' WHEN EXISTS (SELECT 1 FROM license l WHERE l.node_id = n.id AND l.type = 'Type3') THEN 'Status2' ELSE NULL -- 可替换为你需要的默认值 END AS status FROM node n;
对应LINQ实现方案
1. Entity Framework/LINQ to SQL 写法(直接映射SQL逻辑)
用Any()模拟SQL中的EXISTS,嵌套三元表达式实现分支判断:
// 查询语法 var query = from n in dbContext.Nodes select new { n.Id, Status = dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type1") && dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type2") ? "Status1" : dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type3") ? "Status2" : null }; // 方法链语法 var query = dbContext.Nodes.Select(n => new { n.Id, Status = dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type1") && dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type2") ? "Status1" : dbContext.Licenses.Any(l => l.NodeId == n.Id && l.Type == "Type3") ? "Status2" : null });
2. 内存集合(LINQ to Objects)写法
如果数据已经加载到内存,逻辑一致,无需上下文:
var nodes = GetNodesList(); // 假设是内存List<Node> var licenses = GetLicensesList(); // 内存List<License> var result = nodes.Select(n => new { n.Id, Status = licenses.Any(l => l.NodeId == n.Id && l.Type == "Type1") && licenses.Any(l => l.NodeId == n.Id && l.Type == "Type2") ? "Status1" : licenses.Any(l => l.NodeId == n.Id && l.Type == "Type3") ? "Status2" : null });
3. 内存集合优化版(减少重复遍历)
多次Any()会重复扫描license列表,提前分组可提升效率:
// 先按NodeId分组,把对应类型存入HashSet var licenseTypeGroups = licenses.GroupBy(l => l.NodeId) .ToDictionary(g => g.Key, g => g.Select(l => l.Type).ToHashSet()); var result = nodes.Select(n => { licenseTypeGroups.TryGetValue(n.Id, out var nodeTypes); return new { n.Id, Status = nodeTypes != null && nodeTypes.Contains("Type1") && nodeTypes.Contains("Type2") ? "Status1" : nodeTypes != null && nodeTypes.Contains("Type3") ? "Status2" : null }; });
内容的提问来源于stack exchange,提问作者A Cameron
相关产品推荐
相关产品推荐

