如何根据客户端提供的值对 Entity Framework 查询进行动态排序?
我有 2 个用户输入:一个是筛选项目所依据的值,另一个是对结果进行排序的方式 - 按日期、状态、优先级或类型。
数据显示在网格中。
我有一个这样的查询:
Expression<Func<Issue, object>> sortExpression = IssuesConversionsFilter.Convert(sortBy);
Requests = query.Where(i => i.Project.ProjectID == projectId && i.Project.Enabled)
.OrderByDescending(sortExpression)
.Skip(( currentPage - 1 )*take)
.Take(take)
IssuesConversionFilter 是一个静态类,具有由枚举键控的缓存和值为 Expression<Func<Issue, object>>
的值:
internal static class IssuesConversionsFilter
{
readonly static IDictionary<IssuesSortBy, Expression<Func<Issue, object>>> Cache = new Dictionary<IssuesSortBy, Expression<Func<Issue, object>>>();
static IssuesConversionsFilter() {
Cache.Add(IssuesSortBy.Date, i => i.CreatedDate);
Cache.Add(IssuesSortBy.Priority, i => i.Priority);
Cache.Add(IssuesSortBy.Type, i => i.Type);
Cache.Add(IssuesSortBy.State, i => i.State);
}
public static Expression<Func<Issue, object>> Convert(IssuesSortBy sortBy) {
if(Cache.ContainsKey(sortBy) == false)
throw new InvalidOperationException();
return Cache[sortBy];
}
}
返回类型必须是返回 object
的表达式的问题而 LINQ to Entities 似乎只支持原始类型。使用 LING-to-Objects 这很好用。
我怎样才能让它工作?
最佳答案
与其尝试让帮助器类能够返回可在 OrderBy(Descending) 方法调用中使用的通用表达式(您发现当数据类型不完全相同时这很困难) ,在辅助方法中执行对 OrderBy(Descending) 的调用会容易得多。例如:
internal static class IssuesConversionsFilter
{
public static IOrderedQueryable<Issue> Convert(IQueryable<Issue> query, IssuesSortBy sortBy)
{
switch (sortBy)
{
case IssuesSortBy.Date:
return query.OrderByDescending(i => i.CreatedDate);
case IssuesSortBy.Priority:
return query.OrderByDescending(i => i.Priority);
case IssuesSortBy.Type:
return query.OrderByDescending(i => i.Type);
case IssuesSortBy.State:
return query.OrderByDescending(i => i.State);
default:
throw new ArgumentOutOfRangeException("sortBy");
}
}
}
然后你可以像这样使用那个方法:
var orderedQuery = IssuesConversionsFilter.Convert(unOrderedQuery, IssuesSortBy.Date);
您还可以更改 Convert 方法的签名以包含 this
:
public static IOrderedQueryable<Issue> Convert(this IQueryable<Issue> query, IssuesSortBy sortBy)
然后您就可以将它用作扩展方法。这样,您将保持示例中流畅的调用风格:
var Requests = query.Where(i => i.Project.ProjectID == projectId && i.Project.Enabled)
.Convert(sortBy)
.Skip(( currentPage - 1 )*take)
.Take(take)
关于c# - LINQ to Entities 根据客户端输入对表达式进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7364314/