2010-11-25 2 views
2

ich die folgende Linq-Abfrage haben, dieLINQ: Hilfe mit groupby, scheint nicht wie SQL zu arbeiten :-) Lässt mich nur .Key und nichts anderes?

gruppiert
var results = from c in C 
    join h in h on c.Code equals 
     h.Code 
    join m in M on c.Code equals 
     m.Code 
      group c by c.Code into g 
      select 
       new 
       { 
       Group = g.Key, 
       Total = g.Count() 
       } 

funktioniert gut, kehren 2 Datensätze, hat 1 Artikel insgesamt 4 Aufzeichnungen und der andere hat insgesamt 2. Ausgezeichnete seine gruppiert! aber ich gebe nur das gruppierte Feld zurück ...

Es gibt auch ein Feld namens tDate und auf der H-Tabelle und pCode auf der M-Tabelle.

jetzt habe ich versucht, meine Auswahl zu ändern, um zu sagen, aber linqpad beschwert sich über die Variablen m und h, weil ich vermute, sie sind nicht in der Gruppe enthalten von ... Aber das ist, wo ich verloren bin .. wie komme ich zurück mehr Felder in der Gruppe von. Natürlich sind sowohl pCode als auch tDate für jeden Datensatz innerhalb der Gruppe gleich ... daher sollte ich immer noch mit 2 Datensätzen, aber mit mehr Spalten enden.

  select 
       new 
       { 
       Group = g.Key, 
       Total = g.Count(), 
       PCode = m.pCode, 
       TDate = h.tDate 
       } 

Jeder Körper geben Sie mir eine helfende Hand ....

Vielen Dank im Voraus

Antwort

1

Wenn Sie "in" sagen, entfernen Sie alle Variablen aus dem Gültigkeitsbereich, die vor dem into deklariert wurden, und bleiben nur mit der Variablen, die nach dem into deklariert wurde.

var results = 
    from c in C 
    group c by c.Code into g 
    select new 
    { 
    Group = g.Key, 
    Total = g.Count() 
    } into x 
    from c2 in x 
    join h in h on c2.Group equals h.Code 
    join m in M on c2.Group equals m.Code 
    select new 
    { 
    Group = x.Group, 
    Total = x.Total, 
    PCode = m.pCode, 
    TDate = h.tDate 
    }; 
+0

Dank David! Ja, es funktioniert ein Vergnügen! Ich würde gerne wissen, welches der bessere Weg ist, dies zu tun - funktioniert wirklich gut, muss aber mehr Joins nach der ersten Gruppe enthalten. Oder Matoj, wo er vorgeschlagen hat, Max zu verwenden - was auch zu funktionieren scheint und weniger Code ist, aber die Implikationen der Verwendung von Max unsicher sind ... Warum Max verwenden, wenn es keinen Wert (mehrere) gibt, um das Maximum zu erhalten? – Martin

+0

"Warum Max verwenden, wenn": Es gibt einen Plural durch Gruppierung etabliert. Eine Gruppe ist eine Sammlung, auch wenn es nur eine Sache gibt. –

+0

"Was ist besser": Meine Abfrage hat eine Unterabfrage, seine Abfrage nicht. Meine Abfrage-Gruppen in einem Ziel-Zeilensatz, seine Abfrage-Gruppen in der Ergebnismenge. Aus Performance-Sicht ist seine Abfrage möglicherweise besser, da der erste Beitritt dem Optimierer die Wahlmöglichkeiten gibt, wo er anfangen soll. Aus Gründen der Korrektheit würde ich meine Abfrage bevorzugen, da die Gruppierung zuerst alle Fehler aufdeckt, die durch Verbinden mit nicht eindeutigen Datensätzen eingeführt werden (Gruppierung nach dem Verbinden blendet diese Fehler aus). –

2

SQL würden Sie eine Fehlermeldung über die Spalten nicht als Teil einer Aggregatfunktion enthalten ist. Um sie in die Gruppe aufzunehmen, müssen Sie sie in Ihre Gruppe aufnehmen oder in die Daten aufnehmen, um sie mit den gruppierten Daten in Beziehung zu setzen.

+0

Ja genau, würde SQL über die Felder klagt in der Auswahl Teil für Teil in der Gruppe nicht zu sein, aber das ist mein Problem ist, ich verstehe nicht, wie diese – Martin

2

Ich denke, Sie müssen eine Aggregatfunktion verwenden, um den Wert zu erhalten. Haben Sie versucht h.Max(y => y.tDate) und m.First(y => y.pCode)? Ich denke, das könnte funktionieren, aber ich bin mir nicht sicher. Nicht alle Funktionen sind Aggregatfunktionen.

+0

Ja Max arbeitet in Linq transponieren! Ich mag das! Aber. Zuerst nicht. Ist das ein Trick? Gute Übung? Ich nehme an, die Regel dahinter ist, dass man Aggregatfunktionen nur über eine Gruppe zurückgeben kann, wenn man sie nicht explizit zurückgibt. Also macht man einen Max :-)! Ist das die beste Methode? Ich habe ein paar wie First versucht, aber nicht funktioniert ... Max nimmt den Maximalwert, aber da es keine Datensätze mehr gibt gibt es eine Methode, um nur den Wert zu drucken? Etwas wie zuerst - aber zuerst funktioniert nicht. Danke – Martin

+0

'First' funktioniert nicht, da es wahrscheinlich keine Aggregatfunktion ist, denke ich ...Ich habe nur mit dem geraten :). Aber in Ihrem Fall kann man Max für beide Werte verwenden. Ansonsten gibt es hier einen alten Link zum Schreiben eigener Aggregatfunktionen: http://blogs.msdn.com/b/jomo_fisher/archive/2005/09/15/467804.aspx. Ich bin mir nicht sicher, ob es funktioniert, aber Sie könnten es versuchen. 'First' ist kein Trick, es ist einfach keine Aggregatfunktion. –

0

Natürlich sind sowohl pCode als auch tDate für jeden Datensatz innerhalb der Gruppe gleich.

Wenn dies der Fall ist, können Sie sie Teil des Schlüssels machen, um die gewünschten Ergebnisse zu erzielen:

var results = 
     from c in C 
     join h in H on c.Code equals h.Code 
     join m in M on c.Code equals m.Code 
     group c by new { cCode = c.Code, pCode = m.pCode, tDate = h.tDate } 
      into g 
     select 
      new 
       { 
        Group = g.Key, 
        Total = g.Count() 
       }; 

Nun, zum Beispiel, können Sie

var firstcCode = results.First().Group.cCode; 
var firstpCode = results.First().Group.pCode; 
var firsttDate = results.First().Group.tDate; 

Wenn die sagen, Anweisung, die ich zitiert habe ist nicht wahr, dann wie in anderen Antworten vorgeschlagen, wie in SQL, müssen Sie eine Aggregatfunktion aufrufen, um zu sagen, was mit den (möglicherweise viele) pCode Werte für zu tun ein gegebenes cCode.

+0

Danke Aajashm, es funktioniert aber der Schlüssel ist wie eine Sammlung dann .. aber danke - es kann später nützlich – Martin

Verwandte Themen