扩展 Marc Gravell 的动态 Linq OrderBy
我发现了 Marc Gravell 的动态 order by 很棒:
Dynamic LINQ OrderBy on 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 变量传递给函数还很陌生(这让我有点困惑)。我目前收到错误:
OBys.ExecuteOrderBys(q);
这给出了错误:
方法的类型参数 'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)' 无法从用法推断。尝试 指定类型参数 明确地。
如果有人可以帮忙,我对此有点困惑,我是否正确传递了 var q
,然后正确返回它?
I found Marc Gravell's dynamic order by great:
Dynamic LINQ OrderBy on IEnumerable<T>
I've put it in a class, LinqHelper
. In this class I also have created two new classes, so that in my code I can do this:
var q = db.tblJobHeaders;
LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection();
OBys.AddOrderBy("some field", true);
OBys.AddOrderBy("anotherfield", false);
OBys.ExecuteOrderBys(q);
The classes to acheive this are:
/// <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;
}
}
Howver I'm pretty new to passing Linq vars through to functions (the confuses me a bit). I currently get the error on:
OBys.ExecuteOrderBys(q);
Which gives the error:
The type arguments for method
'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)'
cannot be inferred from the usage. Try
specifying the type arguments
explicitly.
I'm a bit confused about this if anyone could help, am I passing the var q
in properly, and then returning it properly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我敢打赌
q
的类型是IQueryable
而不是IOrderedQueryable
。只需更改签名就可以了,因为您是从OrderBy
开始的。然后,您需要为
ThenBy
提供一个IOrderedQueryable
。您可以直接转换它,因为您确信您在之前对OrderBy
或ThenBy
的调用中获得了IOrderedQueryable
。如果您不喜欢强制转换的想法,则需要进行一些更改:
请注意,如果不添加任何排序,您的代码将会严重失败,因为在结尾。您可以将返回类型更改为
IQueryable
(这会失去稍后“附加”更多 OrderBy 的能力),或者如果没有排序,则抛出异常,就像我所做的那样。I bet the type of
q
isIQueryable<T>
and notIOrderedQueryable<T>
. Just changing the signature should work, because you start withOrderBy
.Then you will need an
IOrderedQueryable<T>
for theThenBy
s. You can just cast it, because you know for sure that you have anIOrderedQueryable<T>
from the previous call to eitherOrderBy
orThenBy
.If you don't like the idea of the cast, you need some changes:
Note your code will fail spectacularly if you don't add any orderings, because of the cast to
IOrderedQueryable<T>
in the end. You could change the return type toIQueryable<T>
(which loses the ability to "attach" more OrderBys later), or throw if there are no orderings, like I did.