【问题标题】:LINQ to SQL Query Where ClauseLINQ to SQL 查询 Where 子句
【发布时间】:2011-11-21 05:58:42
【问题描述】:

我想创建一个基于元组“调整”它的 where 子句的单个查询。元组中的第一项包含一个枚举值,指示要过滤的字段。第二个元组项是过滤器值。

请注意下面的查询不起作用:

        var query = from p in db.Categories
        where ( QueryBy.Item1 == CategoryFields.Name        && p.Name        == (string)(QueryBy.Item2) ) ||
              ( QueryBy.Item1 == CategoryFields.Id          && p.Id          == (long)(QueryBy.Item2)   ) ||
              ( QueryBy.Item1 == CategoryFields.Description && p.Description == (string)(QueryBy.Item2) ) ||
              ( QueryBy.Item1 == CategoryFields.SortOrder   && p.SortOrder   == (int)(QueryBy.Item2)    ) 
        select...

        if (query.Count() == 1) // ERRORS HERE CONVERSION OF INT

仅使用此 where 子句更改的类似查询将起作用:

        var query = from p in db.Categories
        where ( QueryBy.Item1 == CategoryFields.Name        && p.Name        == (string)(QueryBy.Item2) )
        select...

        if (query.Count() == 1) // Works HERE

知道有什么问题吗?是不是 LINQ where 子句执行了短路评估,因此 item2 的演员阵容失败了?有没有更好的方法来实现我调整 where 子句的总体目标?

提前感谢您的帮助!

【问题讨论】:

    标签: linq-to-sql


    【解决方案1】:

    LINQ to SQL 不够智能,无法优化您的查询并根据您的 QueryBy.Item1 的值动态生成它。它只会生成一个 SQL 查询,让 SQL 服务器自行决定。

    当您知道这一点时,错误就有意义了,因为不可能将一个值同时转换为 intlongstring

    在您的情况下,您最好动态生成正确的where 子句。您可以使用PredicateBuilder

    IQueryable<Category> query = db.Categories;
    
    var whereClause = PredicateBuilder.False<Category>();
    
    switch (QueryBy.Item1)
    {
        case CategoryFields.Name:
            long id = (string)QueryBy.Item2;
            whereClause = whereClause.Or(p => p.Name == name);
            break;
    
        case CategoryFields.Id:
            string name = (string)QueryBy.Item2;
            whereClause = whereClause.Or(p => p.Id == id);
            break;
    
        case CategoryFields.Description:
            string des = (string)QueryBy.Item2;
            whereClause =
                whereClause.Or(p => p.Description == des);
            break;
    
        case CategoryFields.Id:
            string sort = (int)QueryBy.Item2;
            whereClause =
                whereClause.Or(p => p.SortOrder == sort);
            break;
    }
    
    query = query.Where(whereClause);
    

    【讨论】:

    • 谢谢史蒂文!这适用于一项更改。最后一行:“query = query.Where(whereClause);”似乎过滤了查询。所以我移动了关于查询的switch语句并将查询更改为:“IQueryable query = (db.Categories...).Where(whereClause);”
    猜你喜欢
    • 1970-01-01
    • 2011-06-24
    • 2015-08-29
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多