简体   繁体   English

基于条件的Linq到SQL OrderBy和ThenBy

[英]Condition based Linq to SQL OrderBy and ThenBy

I have to Query through a list then order it by the selections made by user. 我必须通过列表进行查询,然后通过用户的选择对其进行排序。

User can have 3 levels of ordering. 用户可以有3个订购级别。 (ie: SortByItem1 , SortByItem2 , SortByItem3 ) (即:SortByItem1,SortByItem2,SortByItem3)

This is what i currently have. 这就是我目前所拥有的。

// searchResult is IQueryable
if (SortByItem1 == null && SortByItem2 == null && SortByItem3 == null)
{
    searchResult = searchResult.OrderBy(i => new { i.Name, i.Address }).ThenByDescending(i => i.CreatedDate); 
}
else {
    if(SortByItem1!=null)
    {
        if(SortByItem1=="Name") searchResult=searchResult.OrderBy(i=> i.Name);
        else if(SortByItem1=="Date") searchResult=searchResult.OrderBy(i=> i.CreatedDate);
        else if(SortByItem1=="Address") searchResult=searchResult.OrderBy(i=> i.Address);
    }
    if(SortByItem2!=null)
    {
        if(SortByItem2=="Name") searchResult=searchResult.OrderBy(i=> i.Name);
        else if(SortByItem2=="Date") searchResult=searchResult.OrderBy(i=> i.CreatedDate);
        else if(SortByItem2=="Address") searchResult=searchResult.OrderBy(i=> i.Address);
    }
    if(SortByItem3!=null)
    {
        if(SortByItem3=="Name") searchResult=searchResult.OrderBy(i=> i.Name);
        else if(SortByItem3=="Date") searchResult=searchResult.OrderBy(i=> i.CreatedDate);
        else if(SortByItem3=="Address") searchResult=searchResult.OrderBy(i=> i.Address);
    }
}

As you see this is not a reliable way of ordering. 如您所见,这不是一种可靠的订购方式。 I want to have ThenBy ordering on every other trailing ordering. 我要在所有其他尾随排序上都具有然后按顺序排序。 But simply using ThenBy instead of OrderBy is not allowed by Compiler. 但是编译器不允许简单地使用ThenBy而不是OrderBy。

How do I use multiple ordering for the records here? 如何在此处对记录使用多个排序?

Here is an idea. 这是一个主意。 Instead of calling OrderBy all the time you could just define the ordering expressions, and call OrderBy and ThenBy all at once: 无需一直调用OrderBy ,您只需定义排序表达式,然后一次调用OrderByThenBy

Expression<Func<SearchResultType, string>> first;
Expression<Func<SearchResultType, string>> second;
Expression<Func<SearchResultType, string>> third;

// determine which is which, assignment happens like this:
// first = i => i.Name;

searchResult = searchResult.OrderBy(first).ThenBy(second).ThenBy(third);

An improvement on @Andrei's answer would be to wrap this up in an extension method that you could call directly on any IQueryable<T> (it's easy enough to tweak this for IEnumerable<T> support) @Andrei答案的一个改进是将其包装在一个扩展方法中,您可以直接在任何IQueryable<T>上调用它(对IEnumerable<T>支持进行调整很容易)

public static IQueryable<T> SortBy<T>(this IQueryable<T> src, params Expression<Func<T, object>>[] filters)
{
    if (filters == null)
        return src;

    var result = src.OrderBy(filters.FirstOrDefault());
    foreach (var f in filters.Skip(1))
    {
        result = result.ThenBy(f);
    }
    return result;
}

This would allow for arbitrary sorting eg 这将允许任意排序,例如

// sort by name then by address and finally by date
var sorted = items.SortBy(x => x.Name, x => x.Address, x => x.Date);
// sort by date then by address
var sorted = items.SortBy(x => x.Date, x => x.Address);
// sort by name only
var sorted = items.SortBy(x => x.Name);

Live demo 现场演示

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

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