使用给定属性作为字符串

时间:2012-09-06 16:51:40

标签: c# .net sql linq sql-order-by

我想使用单个通用方法来检索表示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 个答案:

答案 0 :(得分:1)

也许这就是你要找的东西:

Dynamic Linq

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

var result = db.Books.OrderBy( "Discount" ).Take( 3 );

答案 1 :(得分: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()作为GenericOrderByDescending<T>()方法的参数传递。您应该键入db.Boks项的类型而不是T.我的示例对类A的实例数组进行排序,我没有错误,它工作正常。我理解你了吗?

答案 2 :(得分:0)

您可以尝试使用此代码

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

答案 3 :(得分: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 });
}