首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展Marc Gravell的动态Linq OrderBy

扩展Marc Gravell的动态Linq OrderBy
EN

Stack Overflow用户
提问于 2011-05-20 10:20:21
回答 1查看 2.3K关注 0票数 6

我发现马克·格雷维尔的动态秩序是:

Dynamic LINQ OrderBy on IEnumerable

我把它放进了一堂课,LinqHelper。在这个类中,我还创建了两个新类,以便在我的代码中可以这样做:

代码语言:javascript
复制
var q = db.tblJobHeaders;

LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection();
OBys.AddOrderBy("some field", true);
OBys.AddOrderBy("anotherfield", false);
OBys.ExecuteOrderBys(q);

要达到这个目标的课程有:

代码语言:javascript
复制
/// <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传递到函数(这有点让我感到困惑),我还是很新的。目前,我在以下几个方面得到了错误:

代码语言:javascript
复制
OBys.ExecuteOrderBys(q);

这就产生了错误:

'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)‘方法的类型参数不能从用法中推断。尝试显式指定类型参数。

我对此有点困惑,如果有人能帮忙的话,我是否正确地传递了var q,然后正确地返回它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-20 10:24:26

我打赌q的类型是IQueryable<T>而不是IOrderedQueryable<T>。只需更改签名就可以了,因为您从OrderBy开始。

然后,您将需要一个用于IOrderedQueryable<T>ThenBy,您可以直接转换它,因为您肯定知道以前调用OrderByThenBy时有一个IOrderedQueryable<T>

如果你不喜欢演员的想法,你需要做一些改变:

代码语言:javascript
复制
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的能力),或者在没有订单的情况下抛出,就像我做的那样。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6070500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档