我想使用单个通用方法来检索表示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);
}
答案 0 :(得分:1)
答案 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 });
}