繁体   English   中英

Linq 按特定枚举值排序

[英]Linq order by specific enum value

我有一个 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) 后跟 'Primary' 设置为 true 的对象,按 'Name' 排序

3) 后跟“类型”设置为“b”的对象,按“名称”排序

4)然后其余的对象(类型'a'和'c')按名称排序

我该怎么做? 是否可以选择具有特定枚举值的所有对象并在其余对象之前对其进行排序?

您应该能够使用OrderBy / ThenBy来实现这一点:

1) 'IsMain' 设置为 true 的对象需要是第一个(只有 1 个)

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

2) 后跟 'Primary' 设置为 true 的对象,按 'Name' 排序

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

3) 后跟“类型”设置为“b”的对象,按“名称”排序

这似乎是您问题的主要部分

.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);

使用接口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());

请注意,此方法不适用于 Linq2Sql,因为自定义比较器无法转换为 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM