2009-05-18 6 views
2

D'accord,dynamique « Non » par paramètre dans LINQ (ou tout autre code pour cette matière)

Cela peut être très simple ou il peut même ne pas être possible, ou je suis juste avoir un caboche :)

Voici un exemple de ce que je suis en train de faire:

public void SomeMethod(bool include) 
     { 
      using (AccountDataContext db = AccountContextFactory.CreateContext()) 
      { 
       if (include) 
       { 
        var query = from a in db.FundingTypes where a.FundingTypeId == 1 select a; 
       } 
       else 
       { 
        var query = from a in db.FundingTypes where a.FundingTypeId != 1 select a; 
       } 
      } 
     } 

Je voudrais changer dynamiquement = et = sans avoir à écrire toute une nouvelle requête. La requête que j'utilise dans la vie réelle est très grande et je n'aime pas la duplication de code.

Pensée ou idées?

Merci

Répondre

11

Cela semble parfaitement simple.

var predicate = include ? 
    (Func<int, bool>) x=>x == 1 : 
    (Func<int, bool>) x=>x != 1 ; 
var query = from a in db.FundingTypes where predicate(a.FundingTypeId) select a; 
+0

Merci, ça a bien fonctionné! – CodeLikeBeaker

+1

Hmm. Premièrement, cela ne compile pas pour moi (j'avais besoin d'ajouter des parenthèses autour de chaque lambda). Deuxièmement (et la raison pour laquelle j'ai essayé cela) est que cela ne se traduira pas par LINQ à SQL et al. L'invocation de la fonction de prédicat dans la requête introduit un DynamicInvoke dans l'arborescence d'expression ... comme il s'agit d'une requête sur un "db", j'aurais pensé que vous auriez besoin de quelque chose qui traduirait? –

0

Que diriez-vous ceci:

public void SomeMethod(bool include, Func<int, bool> query) 
{ 
    using (AccountDataContext db = AccountContextFactory.CreateContext()) 
    { 
     var query = from a in db.FundingTypes where query(a.FundingTypeId) select a; 
    } 
} 
0

Essayez ceci:

SomeMethod(bool include) 
{ 
    using (AccountDataContext db = AccountContextFactory.CreateContext()) 
    { 
     var query = from a in db.FundingTypes where !include^(a.FundingTypeId == 1) select a; 
    } 
} 

Modifier simplifié la logique avec un XOR

+0

Ooo ... comme rstevens mentionné, l'opérateur XOR devrait simplifier que, pour (a.FundingTypeId = 1!)^Comprennent – dustyburwell

+0

Astuce: dessine la table de vérité. Il n'y a que quatre combinaisons possibles. Une fois que vous avez établi la table de vérité, la simplification devrait être évidente. –

0

Essayez ceci:

var predicate = include 
    ? (Func<FundingType, bool>) f => f.FundingTypeId == 1 
    : (Func<FundingType, bool>) f => f.FundingTypeId != 1 
return (from a in db.FundingTypes select a).Where(predicate); 
+1

N'oubliez pas que la spécification de la langue requiert que le type de l'opérateur conditionnel soit connu, ce qui nécessite qu'au moins l'une des conséquences et l'alternative aient un type. Les Lambdas n'ont pas de types. –

+0

En outre, vous ne pouvez pas écrire une demi-requête là-dedans. Où est le "select" qui va avec "from"? –

+0

Hm, les bons points. J'avais l'intention d'écrire la même réponse que la vôtre mais ça n'a pas vraiment réussi .. –

2

Que diriez-vous ceci:

var query = 
    from a in db.FundingTypes 
    where (a.FundingTypeId == 1) == include 
    select a; 

Joe

+0

Cela a également fonctionné, mais je pense que l'option Func <,> offre un peu plus de flexibilité. Merci! – CodeLikeBeaker

Questions connexes