1

Is there a way how to filter data with an enum property using a string?

This is my function in service layer which takes 2 arguments for paging feature and 3rd argument is for filtering projects by their status.

I want to do something like this projects.Where(x => x.Status == status) but it throws error because I cannot compare enum with string. Is there some workaround for this?

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 };
}

Here is my project model:

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
}

This is my enum which i use for assigning status to projects, tasks etc

public enum Status
{
    New = 1,
    Active = 2,
    OnHold = 3,
    Testing = 4,
    Finished = 5,
    Dropped = 6
}   
5
  • 3
    Do You have to use as parametr of the method as string status? Why don't You use Status status instead? Commented Jan 31, 2017 at 18:27
  • @Tatranskymedved yeah this seems incredibly obvious. Commented Jan 31, 2017 at 18:28
  • 1
    Possible duplicate of how to compare string with enum in C# Commented Jan 31, 2017 at 18:31
  • I send my status info as a string from my angular client to my server but i am not sure if it gonna deserialize my information into Status status parameter in my method. Have to try that. Commented Jan 31, 2017 at 18:43
  • Inspect the answers below and choose one that works, you have multiple options. Alternatively, you could send Status as an integer and cast it to Status. Commented Jan 31, 2017 at 18:51

5 Answers 5

2

You can parse the string to the enum equivalent

Obviously this code is a rough draft to give you an idea and set you on the right track, you'd have to do null checks on the Parse to prevent exceptions, or use 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 };
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can parse the string value:

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 };
}

Comments

1

You're passing string as such:

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 };
}

When you should be passing the enum

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

You could also pass in string, and create a Status variable and with some switch statement, you could set it to the correct enum. I don't like converting a string to an enum as some of the answers show. Error prone in my opinion, you're better off trying to either A) resolve the string to a Status or B) just pass in the Status enum to avoid any conflict.

1 Comment

Or, for the last paragraph, you could just TryParse. Imagine a switch statement for a 50 or 100 size enum that's used for billing codes in a corporate product, it's prone to its own bugs by hardcoding strings and introducing possible spelling mistakes
1

Before you call projects.Where(x => x.Status == status); you should try and parse that string value of status into the Status Enum.

You can use either Enum.Parse which throws an exception if the parse fails or you can use Enum.TryParse that returns a bool based on the success/failure of the parsing operation.

1 Comment

Yeah it was just a rough draft, just wanted to show what I want to archieve.
0

You can easily convert the Status enum to String and filter it. You can even search by part of the Status name if you use the Contains method:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.