经过一定剂量的谷歌搜索和尝试一些事情,没有找到/得到期望的结果后,我决定发布这个问题。将IComparer参数传递给自定义LINQ OrderBy扩展方法
我有一个定制OrderBy
扩展方法和现在正执行OrderBy
操作时,我想传递一个AlphanumComparator
这样的:
return divergences.OrderBy(sort, new AlphanumComparator());
这里的扩展方法:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> collection,
GridSortOptions sortOptions, AlphanumComparator comparer = null)
{
if (string.IsNullOrEmpty(sortOptions.Column))
{
return collection;
}
Type collectionType = typeof(T);
ParameterExpression parameterExpression = Expression.Parameter(collectionType, "p");
Expression seedExpression = parameterExpression;
Expression aggregateExpression = sortOptions.Column.Split('.').Aggregate(seedExpression, Expression.Property);
MemberExpression memberExpression = aggregateExpression as MemberExpression;
if (memberExpression == null)
{
throw new NullReferenceException(string.Format("Unable to cast Member Expression for given path: {0}.", sortOptions.Column));
}
LambdaExpression orderByExp = Expression.Lambda(memberExpression, parameterExpression);
const string orderBy = "OrderBy";
const string orderByDesc = "OrderByDescending";
Type childPropertyType = ((PropertyInfo)(memberExpression.Member)).PropertyType;
string methodToInvoke = sortOptions.Direction == MvcContrib.Sorting.SortDirection.Ascending ? orderBy : orderByDesc;
MethodCallExpression orderByCall;
orderByCall = Expression.Call(typeof(Queryable), methodToInvoke, new[] { collectionType, childPropertyType }, collection.Expression, Expression.Quote(orderByExp));
if(comparer != null)
{
// How can I pass the comparator to the OrderBy MethodCallExpression?
// Using the standard LINQ OrderBy, we can do this:
// elements.OrderBy(e => e.Index, new AlphanumComparator())
}
return collection.Provider.CreateQuery<T>(orderByCall);
}
见代码中的评论我认为我应该通过IComparer
......我该如何处理这个问题?
从根本上说,你在这里有一个问题 - 你期待一个*任意比较器*被转换成SQL。你期望如何工作?如果你在自己的代码中实现了'IComparer',并通过哈希代码进行排序,那么你期望生成的SQL看起来像什么呢? –
@JonSkeet如果我将参数声明为“AlphanumComparator”而不是任意的'IComparer',该怎么办?我只是通过比较器的特定属性,我知道是字符串类型。 –
假设这是您自己的类型,它也有同样的问题:LINQ提供程序中的任何内容都不知道如何处理它。 –