如何在 LINQ C# 中按枚举过滤字符串

How to filter by enum from string in LINQ C#

有没有一种方法可以使用字符串过滤带有枚举 属性 的数据?

这是我在服务层的函数,它有 2 个参数用于分页功能,第 3 个参数用于按项目的状态过滤项目。

我想做这样的事情 projects.Where(x => x.Status == status) 但它会抛出错误,因为我无法将枚举与字符串进行比较。有解决办法吗?

public async Task<ListResult<ProjectDTO>> GetListedProjects(int pageSize, int pageNumber, string status)
{
    var projects = await unitOfWork.ProjectRepository.Get();
    //i cannot filter like this
    projects.Where(x => x.Status == status);
    var orderedProjects = projects.OrderBy(x => x.Name);

    var projectList = orderedProjects.ToPagedList(pageNumber, pageSize);

    var data = projectList.Select(x => ToDTO.ProjectBuild(x)).ToList();
    return new ListResult<ProjectDTO> { Data = data, TotalCount = projectList.TotalItemCount };
}

这是我的项目模型:

public class Project : ManagementBaseClass
{
    [Key]
    public int Id { get; set; }
    public Status Status { get; set; }
    public Priority Priority { get; set; }
    //etc just deleted more properties to make this cleaner
}

这是我的枚举,我用它来为项目、任务等分配状态

public enum Status
{
    New = 1,
    Active = 2,
    OnHold = 3,
    Testing = 4,
    Finished = 5,
    Dropped = 6
}   

您可以将字符串解析为等效的枚举

显然这段代码是一个粗略的草稿,可以给你一个想法并让你走上正确的轨道,你必须对 Parse 进行空检查以防止异常,或者使用 TryParse。

public async Task<ListResult<ProjectDTO>> GetListedProjects(int pageSize, int pageNumber, string status)
{
    var projects = await unitOfWork.ProjectRepository.Get();
    //i cannot filter like this
    projects.Where(x => x.Status == (Status)Enum.Parse(typeof(Status), status));
    var orderedProjects = projects.OrderBy(x => x.Name);

    var projectList = orderedProjects.ToPagedList(pageNumber, pageSize);

    var data = projectList.Select(x => ToDTO.ProjectBuild(x)).ToList();
    return new ListResult<ProjectDTO> { Data = data, TotalCount = projectList.TotalItemCount };
}

你正在通过 string 这样的:

public async Task<ListResult<ProjectDTO>> GetListedProjects(int pageSize, int pageNumber, string status)
{
    var projects = await unitOfWork.ProjectRepository.Get();
    //i cannot filter like this
    projects.Where(x => x.Status == status);
    var orderedProjects = projects.OrderBy(x => x.Name);

    var projectList = orderedProjects.ToPagedList(pageNumber, pageSize);

    var data = projectList.Select(x => ToDTO.ProjectBuild(x)).ToList();
    return new ListResult<ProjectDTO> { Data = data, TotalCount = projectList.TotalItemCount };
}

什么时候应该通过枚举

public async Task<ListResult<ProjectDTO>> GetListedProjects(int pageSize, int pageNumber, Status status)

您还可以传入字符串,并创建一个 Status 变量并使用一些 switch 语句,您可以将其设置为正确的枚举。正如某些答案所示,我不喜欢将 string 转换为 enum。在我看来容易出错,您最好尝试 A) 将字符串解析为 Status 或 B) 只传入 Status 枚举以避免任何冲突。

在调用 projects.Where(x => x.Status == status); 之前,您应该尝试将 status 的字符串值解析到状态枚举中。

您可以使用 Enum.Parse 如果解析失败会抛出异常,或者您可以使用 Enum.TryParse returns 基于解析的 success/failure 的布尔值操作。

可以解析字符串值:

private static TEnum? GetEnum<TEnum>(string value) where TEnum : struct
{
    TEnum result;

    return Enum.TryParse<TEnum>(value, out result) ? (TEnum?)result : null;
}

public async Task<ListResult<ProjectDTO>> GetListedProjects(int pageSize, int pageNumber, string status)
{
    var projects = await unitOfWork.ProjectRepository.Get();
    //i cannot filter like this
    projects.Where(x => x.Status == GetEnum<Status>(status));
    var orderedProjects = projects.OrderBy(x => x.Name);

    var projectList = orderedProjects.ToPagedList(pageNumber, pageSize);

    var data = projectList.Select(x => ToDTO.ProjectBuild(x)).ToList();
    return new ListResult<ProjectDTO> { Data = data, TotalCount = projectList.TotalItemCount };
}

您可以轻松地将 Status 枚举转换为 String 并对其进行过滤。如果您使用 Contains 方法,您甚至可以按状态名称的一部分进行搜索:

projects.Where(x => x.Status.ToString() == status);     //To filter by exact input value

projects.Where(x => x.Status.ToString().Contains(status));     //To filter by part of the name search, for example if the input status is any of "N" or "Ne" or "New", the query returns the row with Status = 1