Hallo Leute
In meinem C# Programm habe ich eine Klasse mit folgendem Aufbau
public class cFach
{
public int ID ;
public int Menge ;
}
Diese verwende ich in einer generischen Liste, die einige Einträge enthält.
Mit Linq möchte ich nun als Ergebnis folgendes haben:
-Alle Einträge nach ID sortiert (sortieren)
-Die ID liegt zwischen 0 und 9999 (filtern)
-Identische ID werden gruppiert und die Menge summiert (kumulieren)
Die Ausgabe soll wieder genauso sein wie die Eingabe.
Bisher habe ich dazu folgendes probiert, bekomme aber immer Fehlermeldungen.
...
List<cFach> fächerliste = new List<cFach>();
cFach f = null;
f = new cFach();
f.ID = 1;
f.Menge = 2;
fächerliste.Add(f);
f = new cFach();
f.ID = 1;
f.Menge = -1;
fächerliste.Add(f);
f = new cFach();
f.ID = 2;
f.Menge = 2;
fächerliste.Add(f);
f = new cFach();
f.ID = 2;
f.Menge = 3;
fächerliste.Add(f);
f = new cFach();
f.ID = 3;
f.Menge = 1;
fächerliste.Add(f);
...
fächerliste = fächerliste.AsEnumerable()
.OrderBy(o => o.ID)
.GroupBy(g => g.ID)
.Select(s => new { ID = s.Key , Menge = s.Sum(sm => sm.Menge)});
Leider klappt diese letzte Zeile im Code nicht und ich habe k.A. was ich anders machen muss. 🙁
Hat jemand einen Tipp wie der Linq Befehl aussehen müsste ?
Grüße Cornflake
Hallo Cornflake,
"klappt nicht" ist keine Fehlermeldung. Sag uns, was genau nicht geht.
Bevor du mit ellenlangen LINQ-Statements um dich schmeisst: Mach es doch schritt für Schritt. Beispielsweise sehe ich nciht, wo du filterst, dass die ID zwischen x und y liegen muss.
Nebenbei: Halte dich an die normalen C#-Code-Conventions.
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hallo Coffeebean
Das mit den Filtern habe ich noch gar nicht angefangen, da es schon in der einfacheren Variante zu einem Fehler kommt.
Aktuell habe ich den Aufruf jetzt folgend umgebaut:
fächerliste = fächerliste.AsEnumerable().OrderBy(o => o.ID).GroupBy(g => g.ID).Select(s => new { ID = s.Key, Menge = s.Sum(sm => sm.Menge) }).ToList();
Die Fehlermeldung lautet:
Fehlermeldung:
Fehler 1 Eine implizite Konvertierung vom Typ "System.Collections.Generic.List<AnonymousType#1>" in "System.Collections.Generic.List<Tool.Model.cFach>" ist nicht möglich.
Hallo,
schreib doch mal ein cFach hinter new.
Anmerkungen:
* Du kannst mit der {}-Konstruktor-Syntax schneller Testdaten erzeugen.
* Das Sortieren nützt Dir dort nichts, also zuerst filtern, dann gruppieren dann sortieren.
Hallo Cornflake,
wenn du jetzt nach der englischen Fehlermeldung suchst, findest du auch was.
IOrderedEnumerable<cFach> one = fächerliste.OrderBy(o => o.ID);
IEnumerable<cFach> two = one.Where(x=>x.ID > 0 && x.ID < 9999);
IEnumerable<IGrouping<int, cFach>> three = two.GroupBy(x => x.ID);
IEnumerable<cFach> four = three.Select(a => new cFach(){Menge = a.Sum(b => b.Menge), ID = a.Key});
Beispielsweise. Dann hast du es Schritt für Schritt. Jetzt noch zusammenfassen, wenn du das magst.
Gruss
Coffeebean
PS: Geht gegen Grundlagen. [Hinweis] Wie poste ich richtig? 1.1 und 1.1.1
EDIT: Im Prinzip, was witte sagte.
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
😃 Super freu
Ja hat geklappt.
@witte: Vielen Dank, die fehlende cFach Angabe war der Grund für die ursprüngliche Fehlermeldung.
@Coffeebean: Super vielen Dank für die ausführliche Variante. Jetzt habe ich so langsam etwas mehr von dem ganzen Linq Zeugs verstanden. Die Variante werde ich auch als Vorlage für weitere Linq Probleme verwenden.
Wegen wie poste ich richtig. Habe schon vorher einiges rum gegoogelt. Aber endweder waren die Schlüsselworte falsch oder gab immer nur Lösungen für einspaltige Liste.
Falls du einen Link zu einem guten Linq Tutorial hast, dass dieses Thema nicht nur mit einfachsten Basisbefehlen bespricht, würde das mir für Zukunft auch noch sehr gut helfen. Auf der anderen Seite hatte ich schon linq 101 samples mir runtergeladen und bin da aber wieder nicht ganz durchgestiegen.
Grüße Cornflake