任何人都可以解释之间的区别:
tmp = invoices.InvoiceCollection
.OrderBy(sort1 => sort1.InvoiceOwner.LastName)
.OrderBy(sort2 => sort2.InvoiceOwner.FirstName)
.OrderBy(sort3 => sort3.InvoiceID);
和
tmp = invoices.InvoiceCollection
.OrderBy(sort1 => sort1.InvoiceOwner.LastName)
.ThenBy(sort2 => sort2.InvoiceOwner.FirstName)
.ThenBy(sort3 => sort3.InvoiceID);
如果我希望按3项数据订购,哪种方法正确?
答案 0 :(得分:198)
你肯定使用ThenBy
而不是多次OrderBy
来电。 (我假设你问题中的一个片段是用ThenBy
。在撰写本文时,两个片段是相同的。)
我会建议:
tmp = invoices.InvoiceCollection
.OrderBy(o => o.InvoiceOwner.LastName)
.ThenBy(o => o.InvoiceOwner.FirstName)
.ThenBy(o => o.InvoiceID);
请注意每次都可以使用相同的名称。这也相当于:
tmp = from o in invoices.InvoiceCollection
orderby o.InvoiceOwner.LastName,
o.InvoiceOwner.FirstName,
o.InvoiceID
select o;
如果您多次拨打OrderBy
,它会有效地将序列重新排序三次......所以最终的呼叫将有效地成为主导呼叫。你可以(在LINQ to Objects中)写
foo.OrderBy(x).OrderBy(y).OrderBy(z)
这相当于
foo.OrderBy(z).ThenBy(y).ThenBy(x)
因为排序顺序稳定,但绝对不应该:
OrderBy
设计使用的方式。 OrderBy
的要点是提供“最重要的”排序预测;然后使用ThenBy
(重复)指定二级,三级等排序预测。
实际上,可以这样考虑:OrderBy(...).ThenBy(...).ThenBy(...)
允许您为任意两个对象构建单个复合比较,然后使用该复合比较对序列进行一次。这几乎可以肯定你想要的。
答案 1 :(得分:2)
我发现这种区别在尝试以通用方式构建查询时很烦人,所以我做了一个小帮手,以正确的顺序生成OrderBy / ThenBy,因为你喜欢的种类很多。
public class EFSortHelper
{
public static EFSortHelper<TModel> Create<TModel>(IQueryable<T> query)
{
return new EFSortHelper<TModel>(query);
}
}
public class EFSortHelper<TModel> : EFSortHelper
{
protected IQueryable<TModel> unsorted;
protected IOrderedQueryable<TModel> sorted;
public EFSortHelper(IQueryable<TModel> unsorted)
{
this.unsorted = unsorted;
}
public void SortBy<TCol>(Expression<Func<TModel, TCol>> sort, bool isDesc = false)
{
if (sorted == null)
{
sorted = isDesc ? unsorted.OrderByDescending(sort) : unsorted.OrderBy(sort);
unsorted = null;
}
else
{
sorted = isDesc ? sorted.ThenByDescending(sort) : sorted.ThenBy(sort)
}
}
public IOrderedQueryable<TModel> Sorted
{
get
{
return sorted;
}
}
}
根据您的使用情况,有很多方法可以使用它,但是如果您例如将排序列和方向列表作为字符串和bool传递,您可以循环它们并在像这样的开关中使用它们:
var query = db.People.AsNoTracking();
var sortHelper = EFSortHelper.Create(query);
foreach(var sort in sorts)
{
switch(sort.ColumnName)
{
case "Id":
sortHelper.SortBy(p => p.Id, sort.IsDesc);
break;
case "Name":
sortHelper.SortBy(p => p.Name, sort.IsDesc);
break;
// etc
}
}
var sortedQuery = sortHelper.Sorted;
sortedQuery
中的结果按照所需的顺序排序,而不是像其他答案一样反复尝试。
答案 2 :(得分:1)
如果您想要排序多个字段,请转到ThenBy:
像这样list.OrderBy(personLast => person.LastName)
.ThenBy(personFirst => person.FirstName)
答案 3 :(得分:0)
是的,如果您正在玩多个键,则不应使用多个OrderBy。 然后是更安全的赌注,因为它将在OrderBy之后执行。