LINQ to SQL查询Where子句

时间:2011-11-20 20:25:27

标签: linq-to-sql

我想创建一个单独的查询,根据元组“调整”它的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子句的总体目标?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

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);