2010-03-31 4 views
14

Voici un je travaille sur:ordre Linq par agrégat dans la sélection {}

var fStep = 
      from insp in sq.Inspections 
      where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime 
       && insp.Model == "EP" && insp.TestResults != "P" 
      group insp by new { insp.TestResults, insp.FailStep } into grp 

      select new 
      { 
       FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0), 
       CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0), 
       grp.Key.TestResults, 
       grp.Key.FailStep, 
       PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100) 

      } ; 

Je voudrais orderBy un ou plusieurs des champs dans la projection de sélection.

Répondre

16

Le changement le plus simple est sans doute d'utiliser une suite de requête:

var fStep = 
     from insp in sq.Inspections 
     where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime 
      && insp.Model == "EP" && insp.TestResults != "P" 
     group insp by new { insp.TestResults, insp.FailStep } into grp 
     select new 
     { 
      FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0), 
      CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0), 
      grp.Key.TestResults, 
      grp.Key.FailStep, 
      PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100) 

     } into selection 
     orderby selection.FailedCount, selection.CancelCount 
     select selection; 

C'est la plupart du temps équivalent à l'aide de « laisser », pour être honnête - la vraie différence est que let introduit une nouvelle gamme variable, alors qu'une continuation de requête démarre effectivement une nouvelle étendue de variables de plage - vous ne pouvez pas faire référence à grp dans le bit après into selection par exemple.

Il convient de noter que ce exactement même que l'utilisation de deux déclarations:

var unordered = 
     from insp in sq.Inspections 
     where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime 
      && insp.Model == "EP" && insp.TestResults != "P" 
     group insp by new { insp.TestResults, insp.FailStep } into grp 
     select new 
     { 
      FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0), 
      CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0), 
      grp.Key.TestResults, 
      grp.Key.FailStep, 
      PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100) 

     }; 

var fStep = from selection in unordered 
      orderby selection.FailedCount, selection.CancelCount 
      select selection; 
+0

Fonctionne très bien –

+0

c'est très bon. bon travail, jon –

4

envelopper toute requête entre parenthèses et

.OrderBy(x => x.FailedCount).ThenBy(x => x.CancelCount); 
+1

La deuxième '' OrderBy' doit être ThenBy'. –

+0

veuillez montrer l'exemple –

+0

Très simple. Merci David. – mack

1

Vous pouvez déplacer la valeur de sélection pour une affectation let puis construire un ordre par la suite.

var fStep = 
    from insp in sq.Inspections 
    where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime 
     && insp.Model == "EP" && insp.TestResults != "P" 
    group insp by new { insp.TestResults, insp.FailStep } into grp 
    let newInsp = new 
    { 
     FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0), 
     CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0), 
     grp.Key.TestResults, 
     grp.Key.FailStep, 
     PercentFailed = Convert.ToDecimal(1.0 * grp.Count()/tcount * 100) 

    } 
    orderby newInsp.FailedCount, newInsp.CancelCount 
    // or this ... 
    //orderby newInsp.FailedCount 
    //orderby newInsp.CancelCount 
    select newInsp; 
; 
+0

Généré une erreur lors de l'exécution: Impossible de classer par type '<> f__AnonymousType6'2 [System.Int32, System.Int32]'. –

+0

supprimer le 'nouveau ...' et le remplacer par 'orderby newInsp.FailedCount, newInsp.CancelCount' –

+0

Merci Thomas ... N'a jamais essayé de l'exécuter (seulement eu un modèle de données simulé pour s'assurer au moins compilé.) –