【问题标题】:Extending Marc Gravell's Dynamic Linq OrderBy扩展 Marc Gravell 的 Dynamic Linq OrderBy
【发布时间】:2011-08-29 13:19:18
【问题描述】:

我发现 Marc Gravell 的动态顺序非常棒:

Dynamic LINQ OrderBy on IEnumerable<T>

我已经把它放在一个类中,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,然后正确返回它?

【问题讨论】:

    标签: c# linq dynamic sql-order-by linq-to-objects


    【解决方案1】:

    我打赌q 的类型是IQueryable&lt;T&gt; 而不是IOrderedQueryable&lt;T&gt;。只需更改签名即可,因为您以 OrderBy 开头。

    那么您将需要一个IOrderedQueryable&lt;T&gt; 用于ThenBys。你可以直接施放它,因为你确定你有一个来自上一次调用 OrderByThenByIOrderedQueryable&lt;T&gt;

    如果您不喜欢演员表的想法,则需要进行一些更改:

    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&lt;T&gt;。您可以将返回类型更改为 IQueryable&lt;T&gt;(这将失去以后“附加”更多 OrderBys 的能力),或者如果没有订单就抛出,就像我做的那样。

    【讨论】:

    • 谢谢,这似乎可行,但会在 ExecuteOrderBys 中的“ThenBy”语句中引发错误:The type arguments for method 'LinqHelper.ThenBy&lt;T&gt;(System.Linq.IOrderedQueryable&lt;T&gt;, string)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
    • 超级好用!我会检查一切是否正常,非常感谢您的帮助!
    • @Tom:附注:请不要使用ArrayList。将ArrayList 视为已过时。使用List&lt;object&gt;,或者在你的情况下使用List&lt;string&gt;,应该可以正常工作。
    • 对最后的评论感到抱歉。我的意思是List&lt;Ordering&gt;
    • 谢谢 Martin,只是一个简单的问题,所有这些 order bys 都像常规 linq 查询一样延迟执行吗? (我认为是,只是检查)
    猜你喜欢
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 2011-09-01
    • 2018-07-05
    • 2016-02-27
    相关资源
    最近更新 更多