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

如何在C#中用switch case或存储过程按条件过滤数据集?

问题描述

我正在处理一项任务,需在请求中传入Status作为参数,根据该Status以及数据库表中未随请求传入的Key列过滤数据。具体规则如下:

  • 当Status为Incomplete且数据库中Key值为null时,获取符合条件的记录(标记为awaiting)
  • 当Status为Incomplete且数据库中Key值不为null时,获取符合条件的记录(标记为pending review)
  • 当Status为Suspended时,获取符合条件的记录(标记为rejected)
  • 当Status为Succeeded时,获取符合条件的记录(标记为approved)
  • 当Status为Failed时,获取符合条件的记录(标记为Failed)

我编写了如下C#代码,但存在问题,现咨询是否可不使用switch case语句,改用stored procedure实现该需求?

public class StatusRequest
{
    public Status Status { get; set; }
}

public Task<StatusSearchResponse> Handle(StatusRequest request)
{
var projects = Repository.GetProjects(request.Status);
switch (request.Status)
{
    case Status.Incomplete && projects.Any(x => x.Key == null):
        projects.Where(x => x.Status == Status.Incomplete && x.Key == null);
        break;
    case Status.Suspended:
        break;
    case Status.Succeeded:
        break;
    case Status.Failed:
        break;
    default:
        throw new ArgumentOutOfRangeException();
}

var response = new StatusSearchResponse();
response.Projects = projects;
return SystemTask.FromResult(response);
}

解答

现有代码的问题

  1. C#的switch不支持在case中写逻辑表达式(Status.Incomplete && projects.Any(...)属于非法写法),case只能匹配常量值。
  2. Where方法是惰性求值且返回新集合,你直接调用但未赋值回projects,导致过滤逻辑完全不生效。
  3. 除了Incomplete分支,其他分支没有任何实际过滤逻辑,等于未处理。

存储过程实现的可行性

完全可以用存储过程实现该需求,而且把过滤和标记逻辑放到数据库层,能减少不必要的数据传输,提升查询性能,尤其适合数据量较大的场景。

存储过程示例(SQL Server)

假设你的项目表名为Projects,Status字段对应枚举的字符串类型(如果是整数类型,调整参数类型即可),Key为可空列:

CREATE PROCEDURE GetProjectsByStatus
    @Status NVARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT 
        *,
        -- 根据规则生成状态标记
        CASE
            WHEN @Status = 'Incomplete' AND [Key] IS NULL THEN 'awaiting'
            WHEN @Status = 'Incomplete' AND [Key] IS NOT NULL THEN 'pending review'
            WHEN @Status = 'Suspended' THEN 'rejected'
            WHEN @Status = 'Succeeded' THEN 'approved'
            WHEN @Status = 'Failed' THEN 'Failed'
        END AS StatusTag
    FROM Projects
    WHERE Status = @Status;
END
GO

C#调用存储过程示例

public Task<StatusSearchResponse> Handle(StatusRequest request)
{
    // 假设Repository提供调用存储过程的方法,传入参数并返回强类型集合
    var projects = Repository.FetchFromStoredProcedure<Project>("GetProjectsByStatus", 
        new SqlParameter("@Status", request.Status.ToString()));

    var response = new StatusSearchResponse
    {
        Projects = projects.ToList()
    };

    return Task.FromResult(response);
}

额外建议:不用switch和存储过程的替代方案

如果不想用存储过程,也可以用C# 8.0+的模式匹配替代switch,代码更简洁:

public Task<StatusSearchResponse> Handle(StatusRequest request)
{
    var projects = Repository.GetProjects()
        .Where(p => p.Status == request.Status)
        .Select(p => new 
        {
            Project = p,
            Tag = p.Status switch
            {
                Status.Incomplete when p.Key == null => "awaiting",
                Status.Incomplete when p.Key != null => "pending review",
                Status.Suspended => "rejected",
                Status.Succeeded => "approved",
                Status.Failed => "Failed",
                _ => throw new ArgumentOutOfRangeException(nameof(request.Status))
            }
        })
        .ToList();

    var response = new StatusSearchResponse
    {
        Projects = projects.Select(x => x.Project).ToList()
        // 如果需要返回标记,可在此处添加对应字段
    };

    return Task.FromResult(response);
}

内容的提问来源于stack exchange,提问作者Neha Gauda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:05:01