2010-08-19 4 views
3

Dans mon nouveau projet, j'écris énormément de linq. J'ai beaucoup de requêtes LINQ comme ceci:Simplifier et concevoir des requêtes linq

... 
group new {A, B} by new {....} 
into g 
// Calculate select claw 
let SumVal1 = g.Sum(x => x.A.Value1 * func(x.A, x.B))/g.Sum(x => func(x.A, x.B)) 
let SumVal2 = g.Sum(x => x.A.Value2 * func(x.A, x.B))/g.Sum(x => func(x.A, x.B)) 
let SumVal3 = g.Sum(x => x.A.Value3 * func(x.A, x.B))/g.Sum(x => func(x.A, x.B)) 
.... 
// Here could be some calculation, that are not patterned, like: 
let NotPatternedSum1 = g.Sum(x => x.A.Duration) 
... 
select new {SumVal1, SumVal2, SumVal3, ..., NotPatternedSum, ...} 

Comment puis-je simplifier? J'ai beaucoup de requêtes avec ce modèle (Sum (A * func)/Sum (func)) - comment puis-je introduire cela à une seule méthode ou un délégué?

Peut-être avez-vous déjà vu des conseils pour concevoir de grandes requêtes linq? Mon code est composé de 95% linq (je déplace la logique db vers un client). Pls, me donner quelques conseils, peut-être non trivial =)

Et je veux éviter d'utiliser des types non anonymes

Répondre

4

Quelque chose comme ceci (en supposant int valeurs, nous l'espérons la plupart de vos valeurs sont du même type - il est une douleur à faire cela génériquement).

public static int DividingSum<T>(this IEnumerable<T> source, 
    Func<T, int> f1, Func<T, int> f2) 
{ 
    return source.Sum(t => f1(t) * f2(t))/source.Sum(t => f2(t)); 
} 

Si possible, trouver de meilleurs noms que f1 et f2 bien :)

Vocation:

let SumVal1 = g.DividingSum(x => x.A.Value1, func) 

Cela suppose LINQ to Objects ... LINQ to SQL (ou entités) rendrait cela plus difficile, mais probablement pas impossible.

EDIT: En réponse au commentaire, vous souhaitez simplement changer l'appel à:

let SumVal1 = g.DividingSum(x => x.A.Value1, x => func(x.A, x.B)) 
+0

Thnx, assez simple - mais j'ai un problème avec la mise en œuvre donnée. Ma valeur g est IEnumerable (ou IGrouping ?) Et ma fonction ne peut pas accepter les types anonymes comme arguments – Archeg

+0

@Archeg: J'ai modifié la réponse pour ajouter un exemple supplémentaire en bas. –

+0

Wow, thnx. Quant à moi - très cool, j'ai été très surpris quand VS a montré la liste des membres xA, xB dans le dernier lambda =) Thnx beaucoup – Archeg