2010-11-18 3 views
2

У меня есть таблица базы данных, содержащая «команды» и «состояния». Каждая команда может иметь несколько состояний, и пользователь может настроить это при поиске. Например, команда может быть «Run», и она может иметь два состояния: «Fast» и «Slow».Расширенный поиск базы данных с помощью справки linq-to-sql

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

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

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

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

потому, что когда-то он ищет «Run», «Прогулка» остались бы из результатов так просящих «Прогулка» приведет никаких результатов.

Кто-нибудь знает, как это сделать?

ответ

7

Использование Джо Albahari-х 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); 
+0

+1 стопорное - почти :) –

+0

это очень актуально на самом деле (предикат строитель), так как я ковылял в конце агрегирования, где клаузулы - приятная находка. как ваш успех обходится с ним? –

+0

@jim: На самом деле у меня еще не было необходимости. Большая часть того, что мы делаем, либо достаточно проста, чтобы не нуждаться в ней, либо достаточно продвинута, что мне все равно нужно построить все дерево выражений вручную. Если вы используете PredicateBuilder, вы можете вообще взглянуть на LinqKit. У этого есть некоторые удобные функции для вызова предикатов и вещей. – StriplingWarrior

Смежные вопросы