【发布时间】:2014-02-13 21:21:51
【问题描述】:
我正在使用一个开源系统,并被要求按与术语的相关性对一组实体进行排序。
该集合需要首先以完全匹配排序,然后是“startswith”匹配,然后是“contains”匹配。
我想出的 lambda 表达式是:
var results = products.OrderBy(p => p.Name.StartsWith(searchTerm) ? Convert.ToString((char)0) : p.Name);
目前,预先编写的系统的工作方式是调用带有反射的 lambda 表达式实例的 OrderBy 方法,以便对结果进行排序。
为了尽量减少花在这项任务上的时间,我想遵守这个约定。我尝试创建一个 lambda 表达式的实例并将其作为参数传递给 MethodInfo.Invoke(),但由于其中有一个变量,因此会引发异常。
本系统的排序方法代码为:
private IOrderedQueryable<ReferenceProduct> OrderProducts(IQueryable<ReferenceProduct> filteredProducts, String sortExpression, String sortDirection, out String checkedSortExpression, out String checkedSortedDescending)
{
ProductListManager.SortExpression correspondingSortExpression = this.SortExpressions.OrderByDescending(se => String.Equals(se.Code, sortExpression, StringComparison.OrdinalIgnoreCase))
.DefaultIfEmpty(new SortExpression<Guid> { Code = String.Empty, Expression = rp => rp.ProductId })
.FirstOrDefault();
checkedSortExpression = correspondingSortExpression.Code;
checkedSortedDescending = String.Equals("desc", sortDirection, StringComparison.OrdinalIgnoreCase) ? "desc" : "asc";
MethodInfo orderMethod = (checkedSortedDescending.Equals("desc", StringComparison.OrdinalIgnoreCase) ? (Queryable.OrderByDescending) : new Func<IQueryable<Object>, Expression<Func<Object, Object>>, IOrderedQueryable<Object>>(Queryable.OrderBy)).Method.GetGenericMethodDefinition().MakeGenericMethod(typeof(ReferenceProduct), correspondingSortExpression.Expression.ReturnType);
IOrderedQueryable<ReferenceProduct> orderedProducts = orderMethod.Invoke(null, new Object[] { filteredProducts, correspondingSortExpression.Expression }) as IOrderedQueryable<ReferenceProduct>;
return orderedProducts;
}
有人有什么想法吗?
提前致谢。
瑞恩
【问题讨论】:
-
您想要(或需要)使用反射的原因是什么?
-
这是针对的开源系统通过对其他事物的反射来实现的。不清楚为什么会这样写。我不愿意改变它。
-
在您的编辑中,我注意到它使用的是
IQueryable<T>。IEnumerable<T>和IQueryable<T>之间存在巨大的差异。如果是IQueryable<T>,那么您一开始就不应该使用委托;你应该使用Expressions....你能澄清一下吗? -
你能举例说明
sortExpression可能包含的内容,以便我理解这个场景吗?或者ProductListManager.SortExpression是什么? -
注意:我可以向您推荐这个 (stackoverflow.com/a/233505/23354),了解在
IQueryable<T>上进行动态排序的一般方法。创建一个稍微复杂一点的 lambda 并不是什么大困难,但我根本不明白所有部分的来源。