扩展 Marc Gravell 的动态 Linq OrderBy
本文关键字:Linq OrderBy 动态 Marc Gravell 扩展 | 更新日期: 2023-09-27 17:56:57
我发现Marc Gravell的动态顺序很棒:
IEnumerable
我已经把它放在一个班级里,LinqHelper
. 在本课程中,我还创建了两个新类,以便在我的代码中可以执行此操作:
var q = db.tblJobHeaders;
LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection();
OBys.AddOrderBy("some field", true);
OBys.AddOrderBy("anotherfield", false);
OBys.ExecuteOrderBys(q);
实现此目的的类是:
/// <summary>
/// A collection of order bys
/// </summary>
public class OrderByCollection
{
private ArrayList Orderings = new ArrayList();
public OrderByCollection(){ }
/// <summary>
/// Add an order by to this collection
/// </summary>
public void AddOrderBy(string Field, bool Descending)
{
OrderByObj NewObj = new OrderByObj(Descending, Field);
this.Orderings.Add(NewObj);
}
/// <summary>
/// Executes the order bys
/// </summary>
public IOrderedQueryable<T> ExecuteOrderBys<T>(this IOrderedQueryable<T> source)
{
int ExecutionIndex = 0;
foreach (OrderByObj O in this.Orderings)
{
if (ExecutionIndex == 0)
{
if (O.Descending)
source = LinqHelper.OrderByDescending(source, O.Field);
else
source = LinqHelper.OrderBy(source, O.Field);
}
else
{
if (O.Descending)
source = LinqHelper.ThenByDescending(source, O.Field);
else
source = LinqHelper.ThenBy(source, O.Field);
}
ExecutionIndex++;
}
return (IOrderedQueryable<T>)source;
}
}
/// <summary>
/// An order by object
/// </summary>
private class OrderByObj
{
public bool Descending { get; set; }
public string Field { get; set; }
public OrderByObj(bool IsDescending, string DatabaseField)
{
this.Descending = IsDescending;
this.Field = DatabaseField;
}
}
怎么样,我对将 Linq vars 传递给函数很陌生(这让我有点困惑)。 我目前收到错误:
OBys.ExecuteOrderBys(q);
这给出了错误:
方法的类型参数 'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)' 无法从使用情况中推断。尝试 指定类型参数 明确地。
如果有人可以提供帮助,我对此有点困惑,我是否正确地传递var q
,然后正确返回?
我敢打赌q
的类型是IQueryable<T>
而不是IOrderedQueryable<T>
。只需更改签名即可,因为您从 OrderBy
.
然后,您将需要ThenBy
的IOrderedQueryable<T>
。您可以投射它,因为您确定您从上一次调用OrderBy
或ThenBy
中获得了IOrderedQueryable<T>
。
如果你不喜欢演员阵容的想法,你需要一些改变:
public IOrderedQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)
{
if(!this.Orderings.Any())
throw new InvalidOperationException("You need to add orderings");
IOrderedQueryable<T> ordered;
if (this.Orderings[0].Descending)
ordered = LinqHelper.OrderByDescending(source, this.Orderings[0].Field);
else
ordered = LinqHelper.OrderBy(source, this.Orderings[0].Field);
foreach(var ordering in this.Orderings.Skip(1))
{
if (ordering.Descending)
ordered = LinqHelper.ThenByDescending(source, ordering.Field);
else
ordered = LinqHelper.ThenBy(source, ordering.Field);
}
return ordered;
}
请注意,如果不添加任何排序,您的代码将非常失败,因为最终要IOrderedQueryable<T>
强制转换。您可以将返回类型更改为 IQueryable<T>
(这将失去稍后"附加"更多 OrderBys 的能力),或者如果没有排序,就像我一样抛出。