c# - 通过对数据表使用 Iqueryable 进行排序
问题描述
我有以下函数为 jquery 数据表网格准备数据。现在我面临以下数据类型的错误,而不是字符串
无法将类型“System.DateTime”转换为类型“System.Object”。LINQ to Entities 仅支持转换 EDM 基元或枚举类型。
代码:
public GeneralResponse<IEnumerable<Holiday>> GetHolidays(string filter,
int initialPage,
int pageSize,
out int totalRecords,
out int recordFilterd,
int sortColumn,
string sortDirection)
{
var response = new GeneralResponse<IEnumerable<Holiday>>();
totalRecords = 0;
recordFilterd = 0;
filter = filter.Trim().ToLower();
try
{
Expression<Func<Holiday, dynamic>> expr;
switch (sortColumn)
{
case 0:
expr = p => p.HolidayDate;
break;
case 1:
expr = p => p.Name;
break;
case 2:
expr = p => p.ExchangeMarket.Name;
break;
default:
expr = p => p.CreatedOn;
break;
}
var data = holidayRepository.Query(true);
//var data = holidayRepository.GetAll(true).AsQueryable(); previous working one
totalRecords = data.Count();
//filter
if (!string.IsNullOrWhiteSpace(filter))
{
data = data.Where(x => x.Name.ToLower().Contains(filter));
//todo : Add date search as well
}
recordFilterd = data.Count();
//sort
data = sortDirection == "asc" ? data.OrderBy(expr) : data.OrderByDescending(expr);
data = data
.Skip(initialPage * pageSize)
.Take(pageSize);
var result = data.ToList();
response.Data = result;
}
catch (Exception e)
{
response.Error = true;
response.Exception = e;
}
return response;
}
// This method is under generic repository
public IQueryable<T> Query()
{
return Query(false);
}
早些时候我使用的是 IEnumerable,它首先将所有数据加载到列表中,然后执行运行良好的过滤器(但不正确或最佳实践)
现在我被过滤器部分卡住了。如何修复此错误以按所有类型的属性列排序?
我做了很多研究,但找不到任何解决方案。
解决方案
dynamic
或者object
不能用作TKey
EF 的通用参数Queryable.OrderBy
(实际上在任何Queryable
方法表达式中) - 它必须是键的实际类型。这反过来意味着您不能使用公共Expression<Func<...>>
变量来保存keySelector
表达式。
解决方案是在/块.OrderBy[Descending]
内使用条件。switch
case
为了使处理升序/降序选项更容易(并避免表达式重复),首先创建一个简单的自定义扩展方法,如下所示:
namespace System.Linq
{
public static class QueryableExtensions
{
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending)
{
return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
}
}
}
然后将switch
/case
块移到后面
recordFilterd = data.Count();
行并在里面使用上面的辅助方法:
bool ascending = sortDirection == "asc";
switch (sortColumn)
{
case 0:
data = data.OrderBy(p => p.HolidayDate, ascending);
break;
case 1:
data = data.OrderBy(p => p.Name, ascending);
break;
case 2:
data = data.OrderBy(p => p.ExchangeMarket.Name, ascending);
break;
default:
data = data.OrderBy(p => p.CreatedOn, ascending);
break;
}
推荐阅读
- sql - Oracle 中的性能问题(公用表表达式和全局临时表之间的差异)
- javascript - 如何使用 lodash 使用具有布尔值的另一个数组对数组进行子集化
- haskell - Haskell 在 IO 函数中改变状态
- java - 使用 Java - 每 9 个字符宽的行打印四次迭代
- iis - 如何减少 IIS 10 中的请求超时?
- angular - 无法在 Angular 8 中为 window.open(url) 更改 url(路由);
- highcharts - Hightcharts:平滑放大/缩小距离
- javascript - 如何使用选择框从 var total = rate2 * qty2 Dynamicaly 更改 qty2?
- c# - Boxview“线性渐变画笔”
- typescript - 如何在 RichEmbed 中发送成员的头像