在IEnumerable / IQueryable上进行动态LINQ OrderBy排序

16 浏览
0 Comments

在IEnumerable / IQueryable上进行动态LINQ OrderBy排序

我在VS2008示例中找到了一个关于动态LINQ的例子,它允许您使用类似SQL的字符串(例如OrderBy(\"Name, Age DESC\"))进行排序。不幸的是,该方法仅适用于IQueryable。有没有办法在IEnumerable上获得这个功能呢?

0
0 Comments

动态LINQ OrderBy的实现是一个常见的需求,它允许根据运行时的条件对IEnumerable或IQueryable进行排序。然而,在使用动态LINQ OrderBy时,有时会出现一些问题。这篇文章将讨论问题的原因以及如何解决它。

问题的原因是,当使用动态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或IQueryable进行排序了。

以上就是动态LINQ OrderBy问题的原因以及解决方法。希望这篇文章能帮助到使用动态LINQ OrderBy的开发者们。如果想了解更多细节,请参考原文链接:http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html

0
0 Comments

问题的出现原因:需要在IEnumerable / IQueryable上使用动态LINQ的OrderBy方法进行排序,但是默认的LINQ库不提供这样的功能。

解决方法:使用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 / IQueryable上实现动态LINQ的OrderBy方法,从而实现灵活的排序功能。

0
0 Comments

动态LINQ的OrderBy方法可以用于对IEnumerable或IQueryable进行排序。下面的代码提供了实现这些扩展方法的核心逻辑。这些方法可以处理常见的排序需求,包括嵌套属性的排序。

public static IOrderedQueryable OrderBy(
    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上使用,可以通过添加一些包装方法来实现,这些方法通过AsQueryable()方法进行转换。以上的代码是实现动态LINQ的OrderBy方法的核心逻辑。

在这段代码的后面,还提供了一个使用动态查询的示例,该示例结合了动态排序和动态属性访问。这个示例使用了一个Hashtable来缓存动态属性的访问器,以提高性能。

以上就是动态LINQ OrderBy方法在IEnumerable / IQueryable上的实现以及用法说明。这个扩展方法可以方便地对集合进行动态排序,包括嵌套属性的排序。无论是在LINQ-to-Objects还是LINQ-to-SQL等ORM框架中,都可以使用这个方法进行动态排序。

0