c# - LINQ to Entities 根据客户端输入对表达式进行排序

标签 c# entity-framework sorting linq-to-entities expression

如何根据客户端提供的值对 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/

相关文章:

c# EF查询爆炸

python - 在对列表字典进行排序时解决平局

javascript 排序不能正确处理字符串

c# - 从其他线程添加 UserControl

c# - 当实体集 ChangeTracker 发生更改时如何通知 UI

c# - 在 .NET CF 中以编程方式在 WiFi 网络之间切换?

asp.net-mvc - "In clause"通过 LINQ to SQL

Swift - 使用多个条件对对象数组进行排序

c# - 你能从 SqlDataReader 中获取列名吗?

c# - 获取手动构建的 LINQ 表达式的 "Operation could destabilize the runtime."异常