在IEnumerable / IQueryable上进行动态LINQ OrderBy排序
动态LINQ OrderBy的实现是一个常见的需求,它允许根据运行时的条件对IEnumerable
问题的原因是,当使用动态SQL字符串来构造LINQ OrderBy时,属性名称的大小写敏感性可能会导致错误。在上述代码示例中,使用了Marc的ApplyOrder实现,该实现可以处理类似SQL的字符串来构造LINQ OrderBy。然而,在获取属性时,使用了BindingFlags.IgnoreCase来忽略属性名称的大小写。这样可以确保无论属性名称的大小写如何,都能正确地获取属性。
解决方法是对上述代码进行修改,使属性名称不再区分大小写。具体做法是,在获取属性时使用BindingFlags.IgnoreCase标志来忽略属性名称的大小写。代码修改如下:
PropertyInfo pi = type.GetProperty(prop, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
通过这个修改,我们可以确保在使用动态LINQ OrderBy时,不会因为属性名称的大小写问题而出现错误。这样,我们就可以轻松地根据运行时的条件对IEnumerable
以上就是动态LINQ OrderBy问题的原因以及解决方法。希望这篇文章能帮助到使用动态LINQ OrderBy的开发者们。如果想了解更多细节,请参考原文链接:http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html。
问题的出现原因:需要在IEnumerable
解决方法:使用System.Linq.Dynamic.Core库来实现动态LINQ的OrderBy方法。
具体操作步骤如下:
1. 在代码文件的顶部添加using System.Linq.Dynamic;
引用。
2. 使用vehicles = vehicles.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
进行排序。
需要注意的是,如果使用的是dotnet core,需要使用System.Linq.Dynamic.Core库。
此外,可以使用嵌套属性进行排序,例如vehicles = vehicles.AsQueryable().OrderBy("Status.Label ASC, Year DESC").ToList();
。
如果需要在已包含/连接的列上进行排序,可以使用vehicles.Include(v => v.Tire).AsQueryable().OrderBy("Size ASC").ToList()
。
System.Linq.Dynamic.Core库可以从nuget上进行安装,地址为https://www.nuget.org/packages/System.Linq.Dynamic.Core/。
通过使用System.Linq.Dynamic.Core库,我们可以在IEnumerable
动态LINQ的OrderBy方法可以用于对IEnumerable
public static IOrderedQueryableOrderBy ( this IQueryable source, string property) { return ApplyOrder (source, property, "OrderBy"); } public static IOrderedQueryable OrderByDescending ( this IQueryable source, string property) { return ApplyOrder (source, property, "OrderByDescending"); } public static IOrderedQueryable ThenBy ( this IOrderedQueryable source, string property) { return ApplyOrder (source, property, "ThenBy"); } public static IOrderedQueryable ThenByDescending ( this IOrderedQueryable source, string property) { return ApplyOrder (source, property, "ThenByDescending"); } static IOrderedQueryable ApplyOrder ( IQueryable source, string property, string methodName) { string[] props = property.Split('.'); Type type = typeof(T); ParameterExpression arg = Expression.Parameter(type, "x"); Expression expr = arg; foreach(string prop in props) { PropertyInfo pi = type.GetProperty(prop); expr = Expression.Property(expr, pi); type = pi.PropertyType; } Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type); LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); object result = typeof(Queryable).GetMethods().Single( method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T), type) .Invoke(null, new object[] {source, lambda}); return (IOrderedQueryable )result; }
这段代码可以直接使用,但如果要在IEnumerable
在这段代码的后面,还提供了一个使用动态查询的示例,该示例结合了动态排序和动态属性访问。这个示例使用了一个Hashtable来缓存动态属性的访问器,以提高性能。
以上就是动态LINQ OrderBy方法在IEnumerable