2013-04-19 6 views
21

Ich möchte eine Abfrage mit Linq (Liste von Objekten) und ich weiß wirklich nicht, wie es geht, kann ich die Gruppe und die Summe tun, kann aber nicht Rest auswählen die Felder. Beispiel:Wählen Sie mehrere Felder Gruppe von und Summe

ID Value  Name Category 
1 5   Name1 Category1 
1 7   Name1 Category1 
2 1   Name2 Category2 
3 6   Name3 Category3 
3 2   Name3 Category3 

Ich möchte von ID, SUM von Wert zu gruppieren und das Rück alle Felder wie folgt aus.

ID Value  Name Category 
1 12  Name1 Category1 
2 1   Name2 Category2 
3 8   Name3 Category3 
+0

Haben Sie überprüfen? http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b und Ihr Fall: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – Aristos

+0

seit alle Felder scheint einzigartig für jede ID, warum bringst du sie nicht in die Gruppe mit ein? – Habib

+0

Ja, ich kann das tun, aber ich habe mehr Felder als die ... :( – user2112420

Antwort

44

Aktualisiert: Wenn Sie versuchen, für alle Felder zu vermeiden Gruppierung, können Sie Gruppe nur durch Id:

data.GroupBy(d => d.Id) 
    .Select(
     g => new 
     { 
      Key = g.Key, 
      Value = g.Sum(s => s.Value), 
      Name = g.First().Name, 
      Category = g.First().Category 
     }); 

Aber dieser Code setzt voraus, dass für jede Id, die gleichen Name und Category gelten. Wenn dies der Fall ist, sollten Sie eine Normalisierung in Erwägung ziehen, wie es @Aron vorschlägt. Es würde bedeuten, Id und Value in einer Klasse zu halten und Name, Category (und die anderen Felder wären für die gleiche Id) zu einer anderen Klasse zu verschieben, während auch die Id als Referenz. Der Normalisierungsprozess reduziert Datenredundanz und -abhängigkeit.

+0

Ja ich weiß es aber will einfach nicht alle Felder gruppieren, wäre ein anderer Weg, versuche ich zuerst() aber dann wie summiere? – user2112420

+0

Ich habe die Antwort aktualisiert. –

+0

Ja, ich weiß, was sagst du, ich habe meine DB normalisieren, es ist nur ein Ergebnis meiner Abfrage, aber für jede Zeile meiner Abfrage habe ich Werte wiederholen, und ich will sie gruppieren und den Wert summieren. – user2112420

2
void Main() 
{ 
      //Me being lazy in init 
    var foos = new [] 
    { 
     new Foo { Id = 1, Value = 5}, 
     new Foo { Id = 1, Value = 7}, 
     new Foo { Id = 2, Value = 1}, 
     new Foo { Id = 3, Value = 6}, 
     new Foo { Id = 3, Value = 2}, 
    }; 
    foreach(var x in foos) 
    { 
     x.Name = "Name" + x.Id; 
     x.Category = "Category" + x.Id; 
    } 
      //end init. 

    var result = from x in foos 
       group x.Value by new { x.Id, x.Name, x.Category} 
       into g 
       select new { g.Key.Id, g.Key.Name, g.Key.Category, Value = g.Sum()}; 
    Console.WriteLine(result); 
} 

// Define other methods and classes here 
public class Foo 
{ 
    public int Id {get;set;} 
    public int Value {get;set;} 

    public string Name {get;set;} 
    public string Category {get;set;} 
} 
+0

Ich weiß so, aber ich möchte nicht in meiner Gruppe so viele Felder haben, habe ich mehr als 7. – user2112420

+0

@ user2112420 Dann werden Sie Ihre Klasse zu normalisieren müssen – Aron

+0

Es ist ein Ergebnis Abfrage ich tun Sie von der mehrfachen Tabelle und verursachen Sie ein Objekt dieses Typs – user2112420

1

versuchen Sie dies:

var objList = new List<SampleObject>(); 

objList.Add(new SampleObject() { ID = 1, Value = 5, Name = "Name1", Category = "Catergory1"}); 
objList.Add(new SampleObject() { ID = 1, Value = 7, Name = "Name1", Category = "Catergory1"}); 
objList.Add(new SampleObject() { ID = 2, Value = 1, Name = "Name2", Category = "Catergory2"}); 
objList.Add(new SampleObject() { ID = 3, Value = 6, Name = "Name3", Category = "Catergory3"}); 
objList.Add(new SampleObject() { ID = 3, Value = 2, Name = "Name3", Category = "Catergory3"}); 

var newList = from val in objList 
       group val by new { val.ID, val.Name, val.Category } into grouped 
       select new SampleObject() { ID = grouped.ID, Value = grouped.Sum(), Name = grouped.Name, Category = grouped.Category }; 

mit LINQPad zu überprüfen:

newList.Dump();