You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:55:30