Himaan Singh
Himaan Singh

Reputation: 707

Sorting in Entity Framework for certain parameters

I have a search results table in which their is a column that contains limited values that can be

"Completed", "Recruiting", "Active and not Recruiting" 

I want "Recruiting" rows to come first and then "Active and not Recruiting" and at last "Completed".

The expression that I am using is this

List<Search> lst = new List<Search>(); 

var hello = db.tblSomething.Where(em=>em.someid==obj.someid).ToList

foreach(item in hello)
{
   SomeClass obj1 = new SomeClass();
   obj1.Status = hello.Status;   
   lst.Add(obj1);   
}

Status can contain either of three "Completed" , "Recruiting" , "Active and not Recruiting".

What will be the expression for Recruiting Status elements to come first?

Upvotes: 2

Views: 58

Answers (2)

Erik Philips
Erik Philips

Reputation: 54618

I want "Recruiting" columns to come first and then "Active and not Recruiting" and at last "Completed".

Use OrderBy.

DotNetFiddle Example.

    public static void Main()
{
    var list = new List<SomeClass>
    {
        new SomeClass{ Status = "Recruiting"},
        new SomeClass{ Status = "Completed"},
        new SomeClass{ Status = "Active and not Recruiting"},
        new SomeClass{ Status = "Completed"},
        new SomeClass{ Status = "Recruiting"}
    };
    
    PrintList(list);
    
    Console.WriteLine("-");
    
    var sorted = list
        .OrderBy(sc => sc.Status.Equals("Recruiting", StringComparison.OrdinalIgnoreCase)
            ? 0
            : sc.Status.Equals("Active and not Recruiting", StringComparison.OrdinalIgnoreCase)
                 ? 1
                 : sc.Status.Equals("Completed", StringComparison.OrdinalIgnoreCase)
                    ? 2
                    : 3)
        .ToList();
    
    
    PrintList(sorted);

}

public static void PrintList(IEnumerable<SomeClass> list)
{
    foreach(var sc in list) Console.WriteLine(sc.Status);
}

public class SomeClass
{
    public string Status { get; set; }  
}

Results:

Recuiting

Completed

Active and not Recruiting

Completed

Recuiting

-

Recuiting

Recuiting

Active and not Recruiting

Completed

Completed

That's all fine and dandy, but very ugly and really fragile code. Instead I would highly recommend using an Enum and DisplayAttribute.

DotNetFiddle Example

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
                    
public class Program
{
    public enum StatusType
    {
        [Display(Name = "Invalid", Order = -1)]
        Invalid = 0,
        [Display(Name = "Recuiting", Order = 0)]
        Recruiting,
        [Display(Name = "Completed", Order = 2)]
        Completed,
        [Display(Name = "Active and not Recruiting", Order = 1)]
        ActiveAndNotRecruiting
    }
    
    
    public static void Main()
    {
        var list = new List<SomeClass>
        {
            new SomeClass{ Status = StatusType.Recruiting, Id = 1, Name = "Abraham"},
            new SomeClass{ Status = StatusType.Completed, Id = 2, Name = "Ben"},
            new SomeClass{ Status = StatusType.ActiveAndNotRecruiting, Id = 3, Name = "Carl"},
            new SomeClass{ Status = StatusType.Completed, Id = 4, Name = "Dan"},
            new SomeClass{ Status = StatusType.Recruiting, Id = 5, Name = "Erin"}
        };
        
        PrintList(list);
        
        Console.WriteLine("-");
        
        var sorted = list
            .OrderBy(cs => cs.Status.ToDisplay().Order)
            .ToList();
        
        
        PrintList(sorted);

    }

    public static void PrintList(IEnumerable<SomeClass> list)
    {
        foreach(var sc in list) Console.WriteLine("{0}, {1} is {2}", sc.Id, sc.Name, sc.Status.ToDisplay().Name);
    }
    
    public class SomeClass
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public StatusType Status { get; set; }  
    }
}

public static class EnumExtensions
{
    public static DisplayAttribute ToDisplay(this Enum enumValue) 
    {
        return enumValue.GetType()
            .GetMember(enumValue.ToString())
            .First()
            .GetCustomAttributes(false)
            .Where(a => a is DisplayAttribute)
            .FirstOrDefault() as DisplayAttribute;
    }
}

Results:

1, Abraham is Recuiting

2, Ben is Completed

3, Carl is Active and not Recruiting

4, Dan is Completed

5, Erin is Recuiting

-

1, Abraham is Recuiting

5, Erin is Recuiting

3, Carl is Active and not Recruiting

2, Ben is Completed

4, Dan is Completed

The advantage to using an Enum is that the Name of the properties and sort are encapulated into a single logical location. If you want to change the order, you can do so in a single location, making sure that everything else changes and nothing else will break. This also removes the use of magic numbers/strings.

Upvotes: 2

Serg
Serg

Reputation: 22811

Use List<T>.Sort(Comparison<T>) method. Define you comparison for Search as needed. See https://msdn.microsoft.com/en-us/library/w56d4y5z(v=vs.110).aspx

Upvotes: 0

Related Questions