1

我想使用一种单一的通用方法来检索表示 lambda 表达式中的属性的给定字符串的有序列表。

我知道以前有人要求过这个,但它对我不起作用。我试过了,它抛出了错误:

db.Books.OrderByDescending(x => x.GetType().GetProperty("Discount").GetValue(x,null))
        .Take(3);

我现在正在使用这个:

public IQueryable<Book> GetCheapestBooks()
{
    return db.Books.OrderBy(x => x.Discount)
                   .Take(3);
}
4

4 回答 4

1

也许这就是你正在寻找的:

动态链接

有了这个,您可以编写如下查询:

var result = db.Books.OrderBy( "Discount" ).Take( 3 );
于 2012-09-06T16:58:17.153 回答
0

简单的控制台应用程序。

class A
        {
            public int prop1 { get; set; }
            public int prop2 { get; set; }
        }

    class Program
    {
        static IEnumerable<T> GenericOrderByDescending<T>(IEnumerable<T> arg, string property, int take)
        {
            return arg.OrderByDescending(x => x.GetType().GetProperty(property).GetValue(x, null)).Take(take);
        }

        static void Main(string[] args)
        {           
            IEnumerable<A> arr = new List<A>()
                                     {
                                         new A(){ prop1 = 1, prop2 = 2},
                                         new A(){prop1 = 2,prop2 =2},
                                         new A(){prop1 = 3,prop2 =2},
                                         new A(){prop1 = 441,prop2 =2},
                                         new A(){prop1 = 2,prop2 =2}
                                     };

            foreach(var a1 in GenericOrderByDescending<A>(arr, "prop1", 3))
            {
                Console.WriteLine(a1.prop1);
            }
        }
    }

您可以将您的db.Boks.AsEnumerable()as 参数传递给GenericOrderByDescending<T>()方法。您应该键入db.Boks项目的类型,而不是 T。我的示例对类实例数组进行排序A,我没有错误,它工作正常。我理解正确吗?

于 2012-09-06T17:16:54.403 回答
0

您可以尝试使用此代码

public IQueryable<Book> GetCheapestBooks()
{
    db.Books.OrderBy(x => x.Discount).Take(3).AsQueryable<Book>();
}
于 2012-09-06T17:28:17.640 回答
0

您可以创建一个扩展方法来创建属性表达式:

private static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);
    ParameterExpression paramExpr = Expression.Parameter(typeof(T), "obj");
    MemberExpression propExpr = Expression.Property(paramExpr, prop);

    Type funcType = typeof(Func<,>).MakeGenericType(typeof(T), prop.PropertyType);
    Type keySelectorType = typeof(Expression<>).MakeGenericType(funcType);
    LambdaExpression keySelector = Expression.Lambda(funcType, propExpr, paramExpr);

    MethodInfo orderByMethod = typeof(Queryable).GetMethods().Single(m => m.Name == "OrderBy" && m.GetParameters().Length == 2).MakeGenericMethod(typeof(T), prop.PropertyType);
    return (IOrderedQueryable<T>) orderByMethod.Invoke(null, new object[] { source, keySelector });
}
于 2012-09-06T17:53:17.907 回答