【问题标题】:how to construct a dynamic LINQ to Entities ORDER BY clause?如何构造动态 LINQ to Entities ORDER BY 子句?
【发布时间】:2013-06-06 10:29:12
【问题描述】:

我知道如何构造 WHERE 子句,但由于某种原因我无法构造 order by 子句。

IQueryable<ShowList> query = from s in db.ShowList select s;

if (title != null)
{
    query = query.Where(s => s.Title == title);
}

这就是问题所在。我让用户可以选择他们想要排序的列以及他/她想要的是 DESC 还是 ASC。我认为我在 OrderBy () 内部做错了。

“orderBy”变量是用户的输入,“order”变量也是用户的输入。

“orderBy”应该是列名,“order”应该是“desc”或“asc”

if (orderBy != null && order != null)
            {
                switch (order)
                {
                    case "asc":
                        query = query.OrderBy(s => orderBy);
                        break;
                    case "desc":
                        query = query.OrderByDescending(s => orderBy);
                        break;
                    default:
                        query = query.OrderBy(s => orderBy);
                        break;
                }
            }

return query.ToList();

谁能告诉我我做错了什么?

【问题讨论】:

    标签: c# asp.net-mvc linq-to-entities dynamic-programming asp.net-web-api


    【解决方案1】:

    OrderBy 方法的参数为 LINQ 提供了用于对查询结果进行排序的键。所以基本上你目前正在做的就是说,对于包含在orderBy 中的所有实体字符串应该用作键。因此不执行真正的排序。

    但是orderBy 最有可能指定了应该用于排序的属性的名称。如果您不想/不需要让它太复杂,您可以使用另一个开关/案例:

    Func<ShowList, Object> orderByFunc = null;
    switch (orderBy)
    {
        case "Property1":
            orderByFunc = sl => sl.Property1;
            break;
        case "Property2":
            orderByFunc = sl => sl.Property2;
            break;
        // so on
        default:
            orderByFunc = sl => sl.Property1;
            break;
    }
    

    然后,在实际应用排序时:

    case "asc":
        query = query.OrderBy(orderByFunc).AsQueryable();
        break;
    case "desc":
        query = query.OrderByDescending(orderByFunc).AsQueryable();
        break;
    

    【讨论】:

    • 错误 1 ​​无法将类型“System.Linq.IOrderedEnumerable”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少演员表?)
    【解决方案2】:

    您错误地使用了.OrderBy.OrderByDescending。这些中使用的 lambda 表达式应该为每个项目生成一个值。相反,您为每个项目生成相同的值(orderBy 中的任何内容)。你需要做这样的事情:

    Func<ItemType, object> orderByExpression;
    switch (orderBy)
    {
        case "Column1":
            orderByExpression = s => s.Column1;
            break;
        case "Column2":
            orderByExpression = s => s.Column2;
            break;
        ...
        default:
            throw new NotSupportedException();
    }
    
    switch (order)
    {
        case "asc":
            query = query.OrderBy(orderByExpression);
            break;
        case "desc":
            query = query.OrderByDescending(orderByExpression);
            break;
        default:
            throw new NotSupportedException();
    }
    

    【讨论】:

    • 错误 1 ​​无法将类型“System.Linq.IOrderedEnumerable”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少演员表?)
    • 你在query = query.OrderBy()query = query.OrderByDescending() 行上得到了那个?然后你也可以用你的原始代码得到它。
    • 只需将您的声明 IQueryable&lt;ShowList&gt; query 更改为 var queryIEnumerable&lt;ShowList&gt; query
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2013-01-15
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2023-01-13
    相关资源
    最近更新 更多