Ответ 1
var p = ctx.People.OrderBy(p => (p.IsQualityNetwork == 1 || p.IsEmployee == 1) ? 0 : 1)
.ThenBy(p => p.Name);
Мне интересно, если кто-то знает, как выразить в Entity Framework то, что будет в чистом SQL:
SELECT Name, IsEmployee, IsQualityNetwork
FROM Person
ORDER BY CASE WHEN IsQualityNetwork = 1 or IsEmployee = 1 THEN 0 ELSE 1 END, Name
Я пробовал использовать Linq Dynamic, но когда этот код выполняется:
var p = ctx.People
.OrderBy("CASE WHEN IsQualityNetwork = 1 or IsEmployee = 1 THEN 0 ELSE 1 END")
.OrderBy(e => e.Name);
Я получаю исключение: { "Нет свойства или поля" CASE "существует в типе" Лицо ""}
var p = ctx.People.OrderBy(p => (p.IsQualityNetwork == 1 || p.IsEmployee == 1) ? 0 : 1)
.ThenBy(p => p.Name);
Вот перевод вашего SQL в LINQ.
var query = from p in ctx.People
let order = p.IsQualityNetwork || p.IsEmployee ? 0 : 1
orderby order, p.Name
select new
{
p.Name,
p.IsEmployee,
p.IsQualityNetwork,
}
Я использовал свободный синтаксис запроса, чтобы показать вам ключевое слово let
. let
позволяет объявлять переменную диапазона, которая затем может быть повторно использована в вашем запросе, это может быть очень полезно, если у вас есть условие, которое используется во многих местах, или если вам нужно связать несколько условных выражений.
Я создал метод расширения с пользовательской функцией порядка сортировки. он также работает с Entity Framework, передавая порядок в sql
как ORDER BY CASE WHEN..THEN..
просто передайте возвращенное выражение из этого метода в параметр метода .OrderBy()
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);
}
и сказать, что наша модель:
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");
var customOrderCats = cats.AsQueryable().OrderBy(customSortExpression); // works with Entity framework too //orders cat2,cat1,cat3