2009-07-07 11 views
1

J'ai cette requête qui fonctionne mais elle ne retourne pas exactement ce que je cherche.Linq to objects imbriqués group-by

J'ai une collection de:

List<TransactionRecord> transactionLog; 

TransactionRecord simplifié ressemble à quelque chose comme ceci:

class TransactionRecord { 
    public string txSetComments; 
    public string BatchComments; 
    public string TargetComments; 
    public string TargetName; 
    public string TargetValue; 
} 

et peut être initialisé:

List<TransactionRecord> transactionLog = new List<TransactionRecord>() 
{  
    new TransactionRecord { txSetComments = "txc1", 
          BatchComments = "bc1", 
          TargetComments = "tc1", 
          TargetName = "target1", 
          TargetValue = "v1" }, 

    new TransactionRecord { txSetComments = "txc1", 
          BatchComments = "bc1", 
          TargetComments = "tc1", 
          TargetName = "target1", 
          TargetValue = "v2" }, 

    new TransactionRecord { txSetComments = "txc2", 
          BatchComments = "bc2", 
          TargetComments = "tc1", 
          TargetName = "target2", 
          TargetValue = "v3" }, 

    new TransactionRecord { txSetComments = "txc2", 
          BatchComments = "bc1", 
          TargetComments = "tc1", 
          TargetName = "target2", 
          TargetValue = "v4" }, 

    new TransactionRecord { txSetComments = "txc1", 
          BatchComments = "bc3", 
          TargetComments = "tc1", 
          TargetName = "target1", 
          TargetValue = "v5" }, 

    new TransactionRecord { txSetComments = "txc3",  
          BatchComments = "bc3", 
          TargetComments = "tc1", 
          TargetName = "target3", 
          TargetValue = "v6" }   
}; 

Voici la requête jusqu'à présent :

Dictionary<string, Dictionary<string, IEnumerable<TransactionRecord>>> history = 
    transactionLog.GroupBy(tx => tx.TxSetComments) 
     .ToDictionary(g => g.Key, 
         g => g.GroupBy(b => b.BatchComments).ToDictionary(e => e.Key, 
                     e => e.Where(t => t.TargetName == Target))); 

Voici le problème. Si je mets « Target » dans la requête pour « TARGET1 », la plupart du résultat est que j'attendre:

txc1 
    bc1 
     target1/v1 
     target1/v2 
    bc3 
     target1/v5 

C'est un bon début, mais je reçois aussi:

txc2 
txc3 

ajouté à la liste pour un résultat complet qui ressemble comme aime:

txc1 
    bc1 
     target1/v1 
     target1/v2 
    bc3 
     target1/v5 
txc2 
txc3 

Je voudrais que la requête pour renvoyer uniquement des groupes de haut niveau s'il y a un match à « Target ». Dans l'exemple ci-dessus, il renvoie toujours "txc2" et "txc3" en tant que groupes de niveau supérieur, même s'ils ne correspondent pas à la "cible".

J'espère que ce n'est pas trop confus. Des recommandations?

Merci!

Répondre

2

Copiez votre clause Where en dehors de GroupBy.

var history = transactionLog.Where(record => record.TargetName == "target1") 
    .GroupBy(tx => tx.txSetComments) 
    .ToDictionary(
     g => g.Key, 
     g => g.GroupBy(b => b.BatchComments) 
       .ToDictionary(e => e.Key, 
          e => e.Where(t => t.TargetName == "target1")); 
+0

Ah oui, maintenant c'est si évident. C'est la seule. Là où je n'ai pas essayé. Incroyable à quel point nous devenons aveugles après avoir regardé les requêtes linq imbriquées pendant des heures. Merci! – IUnknown