經過一定劑量的谷歌搜索和嘗試一些事情,沒有找到/得到期望的結果後,我決定發佈這個問題。將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提供程序中的任何內容都不知道如何處理它。 –