确定是否已订购IQueryable
有没有办法知道是否已经订购了IQueryable
(使用OrderBy
或OrderbyDescending
)?
所以我知道是否在集合上调用OrderBy
或ThenBy
。
IQueryable contacts = Database.GetContacts();
我试过contacts is IOrderedQueryable
,但它总是如此。
编辑 :我刚刚改变了我的例子,前一个并没有真正表明我的观点。 假设GetContacts
使用Entity Framework并简单地返回表的所有记录。
稍后,我将几个函数应用于contacts
,我不知道这些函数的作用。 他们可以对IQueryable
进行排序或过滤。
当我收回集合时,我需要再次对它进行排序。 为此,我需要知道是否需要调用OrderBy
或ThenBy
。 因此,如果已经对整个集合进行了排序,我不会重新排序。
简短的回答是否定的,Queryable类不维护标志或者是否对集合进行了排序,也没有使用什么方法来执行这样的排序。
https://msdn.microsoft.com/en-us/library/system.linq.queryable.aspx
这是可能的。 这是一个扩展方法:
public static bool IsOrdered(this IQueryable queryable) { if (queryable == null) { throw new ArgumentNullException("queryable"); } return queryable.Expression.Type == typeof(IOrderedQueryable ); }
是的,您可以检查IQueryable.Expression
树以查看它是否调用任何OrderBy/ThenBy
方法。 可以通过从ExpressionVisitor派生类来检查表达式树。
System.Web
有一个内部OrderingMethodFinder
– 您可以调整它。 这就是我想出的:
// Adapted from internal System.Web.Util.OrderingMethodFinder https://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; } }
像这样使用它:
bool isOrdered = OrderingMethodFinder.OrderMethodExists(myQuery.Expression);
实际上,你可以。
我在你的代码中发现的第一个问题就是你没有任何理由将这个集合转换为IQueryable
。
以下片段:
var numbers = new[] {1, 5, 6, 87, 3}; Console.Write(numbers is IOrderedEnumerable); var ordered = numbers.OrderBy(c => c); Console.Write(ordered is IOrderedEnumerable );
甚至不需要运行:第一次检查会给你一个设计时警告说这个表达式永远不会成立。
无论如何,如果你运行它,它会在第一次检查时给你False,在第二次检查时给你True。
您可以使用IQueryable
和IOrderedQueryable
执行相同的操作,只要您真正使用该类型,而不是将集合转换为它。
除非您自己检查订单,否则您永远不会知道对象是否已正确订购。 您的示例很容易看出它们没有被排序,因为数字具有自然顺序,但IQueryable是通用的,这意味着它可以处理不同类型的对象。 say用户对象(FirstName,LastName,DateStart和LastPayDate)的顺序具有任意顺序,因此返回它们的顺序不一定是您要查找的顺序。 (这被认为是排序的主要领域?这取决于你的需要。)因此,理论上,“他们订购了”这个问题总是“是的!” 您要查找的订单可能与系统返回的订单大不相同。
您可以检查查询的ToString()以查明是否使用了Order By。
当连接发生时,IQueryable的ToString将parantheses放入内部查询的begininng和end。 因此,如果您找到最后一个关闭的parantheses,您可以检查您的最外层查询是否具有Order By子句。
private bool isOrdered(IQueryable Data) { string query = Data.ToString(); int pIndex = query.LastIndexOf(')'); if (pIndex == -1) pIndex = 0; if (query.IndexOf("ORDER BY", pIndex) != -1) { return true; } return false; }
我知道它非常脏,但它适用于我的所有情况,我想不出一个例外情况。
上述就是C#学习教程:确定是否已订购IQueryable分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/957338.html