LINQ to SQL Query Where - PullRequest
       1

LINQ to SQL Query Where

1 голос
/ 21 ноября 2011

Я хотел бы создать один запрос, который «корректирует» предложение 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

Аналогичный запрос только с этим, где смена предложения будет работать:

        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 Ответ

3 голосов
/ 21 ноября 2011

LINQ to SQL недостаточно умен, чтобы оптимизировать ваш запрос и генерировать его динамически на основе значения вашего QueryBy.Item1.Он просто сгенерирует запрос SQL, и сервер SQL сам решит это для себя.

Когда вы это знаете, ошибка имеет смысл, поскольку невозможно, чтобы одно значение могло быть преобразовано в оба значения int, longи string.

В вашем случае вам лучше динамически генерировать правильное предложение 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...