Создание выражения OrderBy для LINQ/Lambda
Я создаю доказательство концепции, которая использует Lambda/LINQ для динамических где и orderby. Следующий код работает для выражения where, но я не могу понять, как создать порядок по выражению. Для этого примера, если возможно, я хотел бы сохранить его простым; Я бы предпочел не писать код, который изменяет дерево выражений.
void Main()
{
DateTime productSince = DateTime.UtcNow.Subtract(new TimeSpan(1,30,0));
Expression<Func<Products, bool>> filter = d => d.CreatedDate > productSince && d.Price < 100 ;
List<Products> products = GetProducts(filter, Products);
Console.WriteLine(products);
}
private static List<Products> GetProducts(Expression<Func<Products, bool>> filter, Table<Products> Products)
{
var products = Products.Where(filter);
return products.ToList();
}
То, что я хочу, похоже на следующее, но не может определить код для создания порядка по выражению.
void Main()
{
DateTime productSince = DateTime.UtcNow.Subtract(new TimeSpan(1,30,0));
Expression<Func<Products, bool>> filter = d => d.CreatedDate > productSince && d.Price < 100 ;
Expression<Func<Products, ????>> orderBy = d => ??????;
List<Products> products = GetProducts(filter, orderBy, Products);
Console.WriteLine(products);
}
private static List<Products> GetProducts(Expression<Func<Products, bool>> filter,
Expression<Func<Products, ???>> orderBy, Table<Products> Products)
{
var products = Products.Where(filter).OrderBy(orderBy);
return products.ToList();
}
Если вам интересно, я использую LinqPad для этого доказательства концепции.
Ответы
Ответ 1
private static List<Products> GetProducts<TOrderBy>(Expression<Func<Products, bool>> filter,
Expression<Func<Products, TOrderBy>> orderBy, Table<Products> Products)
{
var products = Products.Where(filter).OrderBy(orderBy);
return products.ToList();
}
Если вы посмотрите на метод расширения OrderBy, он принимает Expression<Func<T, TOrderBy>>
, потому что выражение может приводить к любому типу, зависящему от
.OrderBy(x => x.ID) // <T, int>
.OrderBy(x => x.Name) // <T, string>
Таким образом, ваш метод обертки должен иметь возможность принять этот общий тип, который должен пройти.
Ответ 2
что вы ищете:
Expression<Func<Products, dynamic>>;
попробуйте создать структуру/класс для хранения как выражения, так и возрастания или убывания.