Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
426 views
in Technique[技术] by (71.8m points)

c# - How to know if OrderBy was applied to query?

I need to know if an OrderBy was applied to a Linq query before applying an .Skip or .Take. I have no control of the received query and if an OrderBy was applied I need to maintain this one, in any other case I should OrderBy(t=>true). I have tried the following:

    DataContext db;
    var query = db.Orders;

    var wasOrderByApplied = typeof(IOrderedQueryable<Order>).IsAssignableFrom(query.AsQueryable().Expression.Type);
    var wasOrderByApplied2 = query.AsQueryable().Expression.Type == typeof(System.Data.Entity.Core.Objects.ObjectQuery<Order>);
    var wasOrderByApplied3 = typeof(IOrderedQueryable<Order>) == query.AsQueryable().Expression.Type;

    var query2 = db.Orders.OrderBy(o => o.CreationDate);

    var wasOrderByApplied4 = typeof(IOrderedQueryable<Order>).IsAssignableFrom(query2.AsQueryable().Expression.Type);
    var wasOrderByApplied5 = query2.AsQueryable().Expression.Type == typeof(System.Data.Entity.Core.Objects.ObjectQuery<Order>);
    var wasOrderByApplied6 = typeof(IOrderedQueryable<Order>) == query2.AsQueryable().Expression.Type;

    var query3 = db.Orders.OrderBy(o => o.CreationDate).Where(o => o.Id > 4);

    var wasOrderByApplied7 = typeof(IOrderedQueryable<Order>).IsAssignableFrom(query3.AsQueryable().Expression.Type);
    var wasOrderByApplied8 = query3.AsQueryable().Expression.Type == typeof(System.Data.Entity.Core.Objects.ObjectQuery<Order>);
    var wasOrderByApplied9 = typeof(IOrderedQueryable<Order>) == query3.AsQueryable().Expression.Type;

The results where:

wasOrderByApplied = true;
wasOrderByApplied2 = true;
wasOrderByApplied3 = false;

wasOrderByApplied4 = true;
wasOrderByApplied5 = false;
wasOrderByApplied6 = true;

With the last results it seems that the third question asked to each query is the one that is correct, but then I did the third query (query3) and the results where:

wasOrderByApplied7 = false;
wasOrderByApplied8 = false;
wasOrderByApplied9 = false;

When I add a Where after the OrderBy the question result is false where it should be true.

Is there a better way to know if an OrderBy was applied to the query?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is one possible solution that came to my mind:

Create an expression visitor that checks whether the expression invokes the OrderBy, or the OrderByDescending method like this:

public class MyVisitor : ExpressionVisitor
{
    public bool HasOrderBy { get; private set; }

    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if (node.Method.DeclaringType == typeof (Queryable) &&
            (node.Method.Name == "OrderBy" || node.Method.Name == "OrderByDescending"))
            HasOrderBy = true;

        return base.VisitMethodCall(node);
    }
}

Here is how you can use it:

MyVisitor visitor = new MyVisitor();

visitor.Visit(query.Expression);

if (visitor.HasOrderBy)
{
    //..
}
else
{
    //..
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...