将IComparer参数传递给自定义LINQ OrderBy扩展方法 [英] Passing an IComparer parameter to custom LINQ OrderBy extension method
问题描述
经过大量的Google搜索并尝试了一些事情却没有找到/获得所需的结果后,我决定发布此问题.
After a good dose of Googling and trying some things and not finding/getting the desired result I decided to post this question.
我有一个自定义的OrderBy
扩展方法,现在执行OrderBy
操作时,我想传递一个 AlphanumComparator
像这样:
I have a custom made OrderBy
extension method and now when performing the OrderBy
operation I'd like to pass an AlphanumComparator
like this:
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
...我该如何处理?
See the comment in the code where I think I should pass the IComparer
... how could I approach this?
推荐答案
我不得不采取不同的方法.
I had to approach this differently.
我试图创建一个通用的OrderBy
以与 MvcContrib网格一起使用,但将 IComparer
传递给该自定义OrderBy
表达式无法正常工作.
I was trying to create a generic OrderBy
to be used with MvcContrib Grid, but passing the IComparer
to that custom OrderBy
expression did not work as I imagined it would work.
因此,我创建了这个帮助程序,该帮助程序以点表示法(如Element1.Standard.Chapter.Manual.Name
)接收字符串,然后返回Expression<Func<T, string>>
:
So I created this helper that receives a string in dot notation like Element1.Standard.Chapter.Manual.Name
and then returns an Expression<Func<T, string>>
:
public static Func<T, string> CreateSelectorExpression<T>(string propertyName) where T : class
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(T));
Expression aggregateExpression = propertyName.Split('.').
Aggregate(parameterExpression as Expression, Expression.Property) as MemberExpression;
LambdaExpression exp = Expression.Lambda(aggregateExpression, parameterExpression);
return (Func<T, string>)exp.Compile();
}
然后可以将键入T的表达式(在这种情况下为Divergence
对象类型)传递(请参见func.Invoke
)到标准LINQ OrderBy
运算符,在这里我也可以传递自定义的IComparer
AlphanumComparator
这个:
This expression typed to T (in this case Divergence
object type) can then be passed (see func.Invoke
) to the standard LINQ OrderBy
operator where I can also pass the custom IComparer
AlphanumComparator
like this:
if (sort.Column.Contains("Index"))
{
var func = Helpers.ExtensionMethods.CreateSelectorExpression<Divergence>(sort.Column);
if (sort.Direction == SortDirection.Ascending)
{
return divergences.OrderBy(func, new AlphanumComparator());
}
else
{
return divergences.OrderByDescending(func, new AlphanumComparator());
}
}
这涉及更多的工作,但是以我希望的方式通用地解决了这个问题.
This involved a little bit more work but solved the problem in a generic fashion the way I wanted it to be.
这篇关于将IComparer参数传递给自定义LINQ OrderBy扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!