Laden...

Linq gruppierte Zeilen in Spalten splitten um CSV-Datei zu erzeugen

Erstellt von Cornflake vor 7 Jahren Letzter Beitrag vor 7 Jahren 1.610 Views
C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 7 Jahren
Linq gruppierte Zeilen in Spalten splitten um CSV-Datei zu erzeugen

verwendetes Datenbanksystem: Linq

Hallo Leute

Vllt könnte ihr mir mit einem Linq Befehl helfen.
Als Anforderung soll ich ein Tabelle erzeugen, die eigentlich der dritten Normalform einer Tabelle wiederspricht und bei der ich nicht weiß wie ich die mit Linq realisieren könnte.

Wie in dem Thementitel beschrieben, gruppiere ich in einer Tabelle Spalten und als Aggregatsfunktion sollen in einer Ergebistabelle die Gruppenzeilen als Spalten ausgegeben werden.

Quelltabelle:


Gruppe; ID ; Menge
1;A1;1
2;B1;1
2;B2;2
3;C1;1
3;C2;2
3;C3;3
...

Ausgabetabelle:


//Kopfzeile ist nur optional
Gruppe ; ID Menge1;ID Menge2;ID Menge3;...
1;A1 1
2;B1 1;B2 2 
3;C1 1;C2 2;C3 3
...

Mein bisheriger Linq:


var erg = from e in Quelltabelle
               group e by e.Gruppe into Grp
               orderby Grp.Key.Gruppe
               select new
                 {
                    Grp.Key.Gruppe,
                    ID_Menge =  Grp.Select (s => s.ID + " " + s.Menge)
                 }

Nur wie mache ich daraus eine CSV Datei?

Beste Grüße
Cornflake

3.003 Beiträge seit 2006
vor 7 Jahren

Halte ich erstens nicht für einen besonders geeigneten Fall für Linq, und zweitens kannst du doch einfach den hier machen:


StringBuilder myStringBuilder = new StringBuilder();
erg.ToList().ForEach(element => 
{
    var idString = string.Join(";", element.ID_Menge);
    myStringBuilder.AppendLine($"{element.Gruppe};{idString}");
});

File.WriteAllText(outputFile, myStringBuilder.ToString());

In diesem speziellen Fall ist zeilenweises Einlesen, dabei "manuelles" Umgruppieren, und schließlich eine direkte Ausgabe vermutlich schneller und besser nachvollziehbar.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 7 Jahren

LaTino

Danke für deinen Tip. 😁
Konnte mich da wohl gedanklich von Linq zu wenig lösen.
Das mit dem ForEach direkt als Ausgabestring klappt super.

3.003 Beiträge seit 2006
vor 7 Jahren

Ich wollt's gestern nicht noch editieren, aber wie gesagt, für eine reine "Konvertierung" Textdatei -> Textdatei ist Linq nicht (unbedingt) der beste Weg, besonders, wenn man in den Operationen Zeichenketten verkettet oder andersweitig mehrfach enumeriert werden muss.

Das laesst sich auch in wenigen Zeilen so erschlagen, dass der Leser (im Zweifel dein 12 Monate älteres ich) sofort nachvollzieht, was los ist:


var outputLines = new Dictionary<string, StringBuilder>();
using (var file = new StreamReader("input.csv"))
{
    string line;
    while ((line = file.ReadLine()) != null)
    {
        var splits = line.Split(';');
        if(splits.Length != 3) continue;

        if (!outputLines.ContainsKey(splits[0])) outputLines.Add(splits[0], new StringBuilder(splits[0]));
        outputLines[splits[0]].Append($";{splits[1]} {splits[2]}");
    }
}

using (var file = new StreamWriter("output.csv"))
    outputLines.Select(p => p.Value).ToList().ForEach(p => file.WriteLine(p.ToString())); //sortieren, filtern, was auch immer: hier, nach dem Select/vor dem ForEach ist der Zeitpunkt für Linq.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)