Расширенный поиск в базе данных с помощью справки linq-to-sql - PullRequest
2 голосов
/ 18 ноября 2010

У меня есть таблица базы данных, которая содержит «команды» и «состояния». Каждая команда может иметь несколько состояний, и пользователь может настроить это при поиске. Например, команда может быть «Выполнить» и может иметь два состояния: «Быстро» и «Медленно».

Я хочу найти в моей таблице все команды, называемые «Выполнить» с «Быстрым» или «Медленным». Это довольно просто сделать:

var results = from t in table
              where t.Command == "Run" &&
              (t.State == "Fast" || t.State == "Slow")
              return t;

Однако пользователь также может выполнить поиск команды «Ходить» с состоянием «Быстрый», поэтому запрос будет выглядеть следующим образом:

    var results = from t in table
                  where (t.Command == "Run" &&
                        (t.State == "Fast" || t.State == "Slow")) ||
                  (t.Command == "Walk" &&
                   t.State == "Fast")
                  return t;

Существует возможность для такого большого количества запросов, как этот, и мне интересно, как их объединить в своего рода цикл.

Я не могу сделать это:

foreach(var command in commands)
{
    foreach(var state in command.states)
    {
        results = from t in table
                  where t.Command == command.Command &&
                  t.State == state;
    }
}

потому что, как только он ищет «Выполнить», «Прогулка» будет исключена из результатов, поэтому запрос «Прогулка» вообще не даст результатов.

Кто-нибудь знает хороший способ сделать это?

1 Ответ

7 голосов
/ 18 ноября 2010

Используйте Джо Албахари PredicateBuilder для построения предиката:

var predicate = PredicateBuilder.False<Entry>();
foreach(var command in commands)
{
    foreach(var state in command.states)
    {
        predicate = predicate.Or(p => p.Command == command.Command && p.State == state);
    }
}
var query = table.Where(predicate);

Или более тяжелая версия LINQ:

var commandStates = from c in commands
                    from s in c.states
                    select new {c.Command, State = s};
var predicate = commandStates.Aggregate(
    PredicateBuilder.False<Entry>(),
    (pred, e) => pred.Or(p => p.Command == e.Command && p.State == e.state));
var query = table.Where(predicate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...