Linq заказ по заданному значению c - PullRequest
0 голосов
/ 24 марта 2020

У меня есть IQueryable объектов

class Object
{
    int Id {get; set; }
    TypeEnum Type {get; set; }
    string Name {get; set; }
    bool IsMain {get; set; }
    bool Primary {get; set; }
}

enum TypeEnum
{
    a = 0,
    b = 1,
    c = 2
}

Мне нужно упорядочить его следующим образом:

1) Объект с IsMain, установленным в true, должен быть первым (есть только 1)

2) Далее следуют Объекты с «Первичным», установленным в true, упорядоченным по «Имени»

3) После Объектов с «Типом», установленным в «b», по «Имени»

4) Тогда остальные объекты (типы 'a' и 'c') упорядочены по имени

Как бы я это сделал? Можно ли выделить все объекты с указанным c значением перечисления и упорядочить их раньше остальных?

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Вы должны иметь возможность использовать OrderBy / ThenBy для достижения этой цели:

1) Объект с IsMain, установленным в true, должен быть первым (есть только 1)

.OrderByDescending(o => o.IsMain) //Desc as true > false

2) За ними следуют Объекты с «Первичным», установленным в «Истина», упорядоченным по «Имени»

.ThenByDescending(o => o.IsPrimary) //Desc as true > false

3) Далее Объекты с 'Type', установленным на 'b', упорядоченные по 'Name'

Это, кажется, основная часть вашего вопроса

.ThenByDescending(o => o.Type == TypeEnum.b) //Desc as true > false

4) Затем остальные объекты (типы 'a' и 'c'), упорядоченные по имени

.ThenBy(o => o.Type)

Я сделал предположение, что порядок имен является последним приоритетом. после вышеуказанного:

.ThenBy(o => o.Name)

Всего:

var ordered = myObjects
    .OrderByDescending(o => o.IsMain)
    .ThenByDescending(o => o.IsPrimary)
    .ThenByDescending(o => o.Type == TypeEnum.b)
    .ThenBy(o => o.Type)
    .ThenBy(o => o.Name);

0 голосов
/ 24 марта 2020

Реализация класса с интерфейсом IComparer<MyObject>.

См. Интерфейс IComparer и Метод IComparer.Compare (Object, Object) .

public class MyObjectComparer: IComparer<MyObject> {
    public int Compare(MyObject left, MyObject right) {

            if (left == null) {
                throw new ArgumentNullException(nameof(left));
            }
            if (right == null) {
                throw new ArgumentNullException(nameof(right));
            }

            // Object with 'IsMain' set to true needs to be first
            if (left.IsMain) {
                return right.IsMain ? 0 : 1;
            }
            if (right.IsMain) {
                return -1; // left.IsMain always false at this point
            }

            // Followed by Objects with 'Primary' set to true ordered by 'Name'
            if (left.Primary) {
                if (!right.Primary) { return 1; }
                return left.Name.CompareTo(right.Name);
            }
            if (right.Primary) {
                return -1; // left.Primary always false at this point
            }

            // Followed by Objects with 'Type' set to 'b' ordered by 'Name'
            if (left.Type == TypeEnum.b) {
                if (right.Type != TypeEnum.b) { return 1; }
                return left.Name.CompareTo(right.Name);
            }
            if (right.Type == TypeEnum.b) {
                return -1; // left.Type always != TypeEnum.b at this point
            }

            // Then the rest of Objects (types 'a' and 'c') ordered by name
             return left.Name.CompareTo(right.Name);
        }
}

Затем вы можете передать этот компаратор методу OrderBy LINQ:

using System.Linq;

IEnumerable<MyObject> allObjects;
var result = allObjects.OrderBy(o => o, new MyObjectComparer());

Обратите внимание, что этот подход не будет работать для Linq2 Sql, поскольку пользовательский компаратор не может перевести на SQL. В этом случае перечислите запрос и закажите его в памяти.

var allObjects = _dbContext.MyObjects.ToArray(); // execute Linq2Sql and get objects into memory
var result = allObjects.OrderBy(o => o, new MyObjectComparer()); // now we can work with Linq2Entities with custom comparer
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...