Linq To Sql - Dynamic OrderBy - Case When

Solution 1:

var u = from u in db.users
        orderby u.username == 100 ? 1 : 0 descending
        select u;

Solution 2:

This really works for me:

var queryResult = 
   from o in Source
   orderby (o.ColumnThatSaysOrderByColumn1 ? o.Column1 : o.Column2) descending
   select o

Hope this helps!

Solution 3:

public class Cat 
{
     public string Name {get;set;}
     public Cat(string name) { Name = name; }
}    

var cats = new List<Cat> { new Cat("cat1"), new Cat("cat2"), new Cat("cat3") };
var customSortExpression = new List<string> { "cat2", "cat1", "cat3" }.CustomSortOrder<Cat>("Name");

//custom sort order, works with EF too //orders cat2,cat1,cat3               
var customOrderCats = cats.AsQueryable().OrderBy(customSortExpression);

when used with EF, this generates sql like the following

SELECT [c].[Name]
   FROM [Cats] AS [c]
   ORDER BY CASE
       WHEN [c].[Name] = N'cat2'
       THEN 0 ELSE CASE
           WHEN [c].[Name] = N'cat1'
           THEN 1 ELSE CASE
               WHEN [c].[Name] = N'cat3'
               THEN 2 ELSE 3
           END
       END
    END

Here is my extension method CustomSortOrder<TEntity>.

public static Expression<Func<TEntity, int>> CustomSortOrder<TEntity>(this IList<string> customSortOrderValues, string propName) {

var e = Expression.Parameter(typeof(TEntity), "e");
var prop = typeof(TEntity).GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
var eDotProp = Expression.MakeMemberAccess(e, prop);
var maxLen = customSortOrderValues.Count;

Expression ElseExpression(IList<string> values) {
    var value = values[0];
    var condition = Expression.Equal(eDotProp, Expression.Constant(value));
    var ifTrue = Expression.Constant(maxLen - values.Count);
    Expression ifFalse ;

    if (values.Count == 1) {
        ifFalse = Expression.Constant(maxLen - values.Count + 1);
    }
    else {
        values.RemoveAt(0);
        ifFalse = ElseExpression(values);
    }
    return Expression.Condition(condition, ifTrue, ifFalse);
}

return Expression.Lambda<Func<TEntity, int>>(
    ElseExpression(customSortOrderValues),
        e);
}