确定是否已订购IQueryable <T>

Ber*_*ron 25 c# iqueryable sql-order-by

有没有办法知道是否IQueryable<T>已订购(使用OrderByOrderbyDescending)?

所以我知道是打电话OrderBy还是ThenBy收集.

IQueryable<Contact> contacts = Database.GetContacts();
Run Code Online (Sandbox Code Playgroud)

我试过了contacts is IOrderedQueryable<Contact>,但它总是如此.

编辑:我刚刚改变了我的例子,前一个并没有真正表明我的观点.假设GetContacts使用Entity Framework并简单地返回表的所有记录.

后来,我应用了几个函数contacts,我不知道这些函数是做什么的.他们可以排序或过滤IQueryable<Contact>.

当我收回集合时,我需要再次对它进行排序.为此,我需要知道是否需要打电话OrderBy,或者ThenBy.因此,如果已经对整个集合进行了排序,我不会重新排序.

Zac*_*les 27

这是可能的.这是一个扩展方法:

public static bool IsOrdered<T>(this IQueryable<T> queryable)
{
    if (queryable == null)
    {
        throw new ArgumentNullException("queryable");
    }

    return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
}
Run Code Online (Sandbox Code Playgroud)

  • 这在一些简单的情况下不起作用。例如在这种情况下: ```csharp var query = queryable.OrderBy(e=&gt;e.Id).AsNoTracking(); ``` `queryable.Expression.Type == typeof(IOrderedQueryable&lt;T&gt;)` 将为 `False`。最简单的检查方法就是检查整个表达式是否为“IOrderedQueryable&lt;T&gt;”: ```csharp public static bool IsOrdered&lt;T&gt;(this IQueryable&lt;T&gt; queryable) { return queryable is IOrderedQueryable&lt;T&gt;; } ``` (2认同)

Dun*_*art 8

是的,您可以检查IQueryable.Expression树以查看它是否调用任何OrderBy/ThenBy方法。可以通过从ExpressionVisitor派生类来检查表达式树。

有一个内部OrderingMethodFinder-System.Web你可以适应。这是我想出的:

// Adapted from internal System.Web.Util.OrderingMethodFinder http://referencesource.microsoft.com/#System.Web/Util/OrderingMethodFinder.cs
class OrderingMethodFinder : ExpressionVisitor
{
    bool _orderingMethodFound = false;

    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        var name = node.Method.Name;

        if (node.Method.DeclaringType == typeof(Queryable) && (
            name.StartsWith("OrderBy", StringComparison.Ordinal) ||
            name.StartsWith("ThenBy", StringComparison.Ordinal)))
        {
            _orderingMethodFound = true;
        }

        return base.VisitMethodCall(node);
    }

    public static bool OrderMethodExists(Expression expression)
    {
        var visitor = new OrderingMethodFinder();
        visitor.Visit(expression);
        return visitor._orderingMethodFound;
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

bool isOrdered = OrderingMethodFinder.OrderMethodExists(myQuery.Expression);
Run Code Online (Sandbox Code Playgroud)


Bue*_*ler -2

简短的回答是否定的,Queryable 类不维护标志或集合是否已排序,也不维护可能使用什么方法来执行此类排序。

http://msdn.microsoft.com/en-us/library/system.linq.queryable.aspx

  • 那么,[`.Skip`](http://msdn.microsoft.com/en-us/library/bb357513.aspx)如何能够[抛出异常](http://stackoverflow.com/questions/225481 /how-to-check-for-the-presence-of-an-orderby-in-a-objectqueryt-expression-tree) 当您在无序 EF 集合上使用它时? (9认同)