我在“ThenBy”部分收到了这个错误
Expression of type 'System.Linq.IQueryable`1 cannot be used for parameter of type 'System.Linq.IOrderedQueryable
using Newtonsoft.Json.Linq;
using Common.Constant;
using System.Collections;
using System.Linq.Expressions;
namespace Common
{
public static class LinqHelper
{
public static IOrderedQueryable<TSource> OrderByDefault<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool isInitialQueryable)
{
var ordered = source as IOrderedQueryable<TSource>;
if (ordered == null || isInitialQueryable)
{
return source.OrderBy(keySelector); // <<-- no issue for this line. the system will get into here for the first column
}
else
{
return ordered.ThenBy(keySelector); // <<-- this line will prompt above error
}
}
}
}
想法是,系统应该能够生成用于排序的代码。这些代码运行第一个“if 语句”没有问题。但是在“else 语句”上会失败
出于某种原因,检查总是返回 true,可查询总是有序的。不能 100% 确定为什么会这样。也许查询提供者在对它进行任何其他工作之前从一开始就将其作为有序可查询生成。
此方法检查可查询对象的排序方式是否在我测试时似乎有效:
public static IOrderedQueryable<TSource> OrderByDefault<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool isInitialQueryable)
{
if (source.Expression.Type != typeof(IOrderedQueryable<TSource>) || isInitialQueryable)
{
return source.OrderBy(keySelector);
}
else
{
return (source as IOrderedQueryable<TSource>).ThenBy(keySelector);
}
}
我也在 if 语句中尝试了一个版本,但它总是会在 OrderBy 部分结束:
if (!typeof(IOrderedQueryable<T>).IsAssignableFrom(source.Expression.Type) || isInitialQueryable)
根据 Svyatoslav Danyliv 的回复,我已将参数从“this IQueryable source”更改为“IOrderedQueryable source”
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IOrderedQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool isInitialQueryable, bool isDescending)
{
if (isInitialQueryable)
{
if (isDescending)
{
return source.OrderByDescending(keySelector);
}
else
{
return source.OrderBy(keySelector);
}
}
else
{
if (isDescending)
{
return source.ThenByDescending(keySelector);
}
else
{
return source.ThenBy(keySelector);
}
}
}
以下是我如何使用该功能的示例
private IOrderedQueryable<Mt_User> PopulateSortingCondition(SortingInfo[] criteria, IQueryable<Mt_User> source)
{
var initialQuery = source as IOrderedQueryable<Mt_User>;
IOrderedQueryable<Mt_User> result = null;
var isResetCondition = true;
var isUnhandledField = false;
if (criteria != null && criteria.Any())
{
foreach (var field in criteria)
{
isUnhandledField = false;
switch (field.Selector)
{
case "COMPANYDESCR":
result = initialQuery.OrderBy(Mt_User => (Mt_User.Account.CODE + " - " + Mt_User.Account.COMPANYNAME + " - " + Mt_User.Account.DESCR), isResetCondition, field.Desc);
break;
case "ACCESSRIGHT":
result = initialQuery.OrderBy(Mt_User => (Mt_User.Role.CODE), isResetCondition, field.Desc);
break;
case "USERNAME":
result = initialQuery.OrderBy(Mt_User => (Mt_User.Contact.NAME), isResetCondition, field.Desc);
break;
default:
isUnhandledField = true;
break;
}
if (!isUnhandledField)
{
initialQuery = result;
isResetCondition = false;
}
}
}
if (result == null)
{
result = initialQuery
.OrderBy(Mt_User => Mt_User.Contact.NAME)
.ThenBy(Mt_User => Mt_User.Role.CODE)
.ThenBy(Mt_User => Mt_User.Account.CODE + " - " + Mt_User.Account.COMPANYNAME + " - " + Mt_User.Account.DESCR);
}
return result;
}