经过大量的谷歌搜索和尝试一些事情而没有找到/得到所需的结果后,我决定发布这个问题。
我有自定义的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
...我该如何处理?
答案 0 :(得分:0)
我必须采用不同的方法。
我正在尝试创建与MvcContrib Grid一起使用的通用OrderBy
,但将IComparer
传递给该自定义OrderBy
表达式并不像我想象的那样有效工作
所以我创建了这个帮助器,它接收一个点符号的字符串,如Element1.Standard.Chapter.Manual.Name
,然后返回一个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
对象类型)传递给标准LINQ func.Invoke
运算符(参见OrderBy
),我也可以在其中传递自定义{ {1}} IComparer
喜欢这样:
AlphanumComparator
这涉及更多的工作,但以我想要的方式以通用的方式解决了问题。