2010-11-18 14 views
2

J'ai une table de base de données qui contient "commands" et "states". Chaque commande peut avoir plusieurs états, et l'utilisateur est capable de configurer cela lors de la recherche. Par exemple, la commande pourrait être "Exécuter" et elle pourrait avoir deux états: "Rapide" et "Lent".Recherche de base de données avancée à l'aide de linq-to-sql help

Je veux rechercher dans ma table toutes les commandes appelées "Run" avec "Fast" ou "Slow". C'est assez simple:

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

Toutefois, l'utilisateur peut également rechercher la commande « Walk » avec l'état « rapide », et donc la requête ressemblerait à ceci:

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

Il y a un potentiel de autant de recherches comme celle-ci, et je me demande comment les combiner en une sorte de boucle.

Je ne peux pas le faire:

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

car une fois qu'il cherche « Run », « Walk » seraient exclus des résultats afin de demander « Walk » entraînerait aucun résultat du tout.

Est-ce que quelqu'un connaît un bon moyen de le faire?

Répondre

7

Utilisez Joe Albahari de PredicateBuilder pour construire un prédicat:

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

Ou une version plus lourde 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 pression - presque :) –

+0

ce qui est très rapide en fait (le prédicat constructeur) comme je l'ai boitillé le long de l'agrégation en retard où les clauses - belle trouvaille. Comment est votre succès avec ça? –

+0

@jim: Je n'en ai pas encore eu besoin. La plupart de ce que nous faisons est soit assez simple pour ne pas en avoir besoin, soit assez avancé pour que je construise tout l'arbre d'expression à la main. Si vous utilisez PredicateBuilder, vous pouvez généralement consulter LinqKit. Il a quelques fonctionnalités pratiques pour invoquer des prédicats et des choses. – StriplingWarrior