Autor |
Beitrag |
Chocoemilio
Beiträge: 38
|
Verfasst: Do 02.08.18 12:11
Hi
Ich bräuchte mal wieder Hilfe und zwar geht es um Otto.OttoTool_Control DB (siehe EntwicklerEcke Bild).
In der Tabelle sollen per Linq pro spalte alle Personen Gruppiert und aufgezählt werden. So das ich die Namen + die Aufzählung im DataGrid angezeigt bekomme.
Quelltext 1: 2: 3: 4:
| z.b : packet_list packing delivery_note
Tobias Ruhe 12 Tobias Ruhe 3 Tobias Ruhe 3 Ferhat Ipek 10 usw. |
Ich habe schon was geschrieben das leider nicht richtig funktioniert:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var query1 = (from t in temp group t by new { t.packet_list, t.packing, t.delivery_note } into grp select new { grp.Key.packet_list, grp.Key.packing, grp.Key.delivery_note, Quantity = grp.Count() }).ToList(); |
Das Ergebnis:
Quelltext 1: 2: 3: 4: 5:
| packet_list packing delivery_note
Tobias Ruhe 9 Ferhat Ipek 10 Tobias Ruhe 3 Tobias Ruhe 3 Tobias Ruhe 3 |
Ich habe einiges problert aber komme auf kein richtiges Ergebnis ?????
Danke schon mal.
Moderiert von Th69: Code-Tags hinzugefügt
Einloggen, um Attachments anzusehen!
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 02.08.18 12:29
Wenn du nur nach Namen sortieren willst, dann gib auch nur t.packet_list beim group by an.
Aber was soll denn dann für packing und delivery_note ausgegeben werden (diese können sich ja je Datensatz unterscheiden)? Ich verstehe deine beiden Tabellenausgaben nicht (welche ich mal in Code-Tags gepackt habe, wegen besserer Formatierung).
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Do 02.08.18 12:42
Hi
In jeder spalte können unterschiedliche Namen stehen und die verschiedenen Namen sollen per spalte aufgezählt werden.
In dem Bild erkennt man das Tobias Ruhe in der spalte packet_list 12 mal vorkommt und Ferhad 10 mal.
In packing und delivery_note sind jeweils Tobias Ruhe 3 mal vorhanden.
Die zweite Tabelle ist das resultat von der Linq abfrage.
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 02.08.18 12:53
Achso, dann wirst du aber je Spalte eigene Abfragen dafür schreiben müssen (bzw. Unterabfragen).
Zuerst müßtest du allerdings eine Liste aller verschiedenen Namen erzeugen (falls in den anderen Spalten Namen vorkommen, welche nicht in der ersten Spalte auftauchen).
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Do 02.08.18 14:05
Ok ok
ich verstehe habe da jetzt was gebastelt und die zahlen stimmen auch aber irgendwie gefällt es mir nicht richtig.
Vielleicht gibt es eine bessere Methode ?????
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| var query1 = (from t in temp group t by new { t.packet_list } into grp select new { grp.Key.packet_list, Quantity = grp.Count(), packing = (from c in temp group c by new { c.packing } into grc select new { grc.Key.packing, Quantity = grc.Count() }), delivery_note = (from c in temp group c by new { c.delivery_note } into grc select new { grc.Key.delivery_note, Quantity = grc.Count() }) }).ToList(); |
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 02.08.18 14:48
Ja, so ähnlich meinte ich es.
Aber müßtest du nicht in den Unterabfragen noch eine Bedingung für grp.Key.packet_list einbauen (denn sonst hast du doch jeweils die gleichen Unterabfragen)?
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Do 02.08.18 15:25
Ich weiß nicht genau was du meinst ???
Habe auch das Problem das ich auf die Unterabfragen Ergebnisse nicht ran komme ???
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 02.08.18 17:07
Deine Unterabfragen für packing (sowie delivery_note) sind so für jedes Element grp.Key.packet_list gleich.
Müßtest du nicht so etwas machen:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| packing = (from c in temp where c.packing = grp.Key.packet_list group c by new { c.packing } into grc select new { grc.Key.packing, Quantity = grc.Count() }), |
(bzw. das group by kannst du dann weglassen, da es ja eh nur 1 Gruppe gibt)
PS: So ist jedoch packing eine Liste (wenn auch nur mit 1 Element). Du müßtest also noch .FirstOrDefault() hinzufügen.
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Fr 03.08.18 09:04
Hi
ja Danke ich verstehe aber leider kriege ich die Daten nicht so raus wie ich möchte .
Naja dann nehme ich den langen Weg und bestell mir eine neue Liste.
Danke nochmal für die Hilfe
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Fr 03.08.18 16:14
Die fertige Liste:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245:
| private void anzeige_Click(object sender, RoutedEventArgs e) { int count = 0; int count1 = 0; int count2 = 0; int count3 = 0; int count4 = 0; int count5 = 0; string[] allpacketListEmployee = new string[1]; string[] allpackedUpEmployee = new string[1]; string[] alldeliveryNoteEmployee = new string[1]; string[] allcardboardLabelsEmployee = new string[1]; string[] allpalletsEmployee = new string[1]; string[] alldeliveryInsideEmployee = new string[1];
DateTime date1 = DateTime.Now; DateTime date2 = DateTime.Now;
if (vonDatum.Text != Convert.ToString(date1.ToString("d")) && bisDatum.Text != Convert.ToString(date2.ToString("d")) || vonDatum.Text != Convert.ToString(date1.ToString("d")) && bisDatum.Text == Convert.ToString(date2.ToString("d")) || vonDatum.Text == Convert.ToString(date1.ToString("d")) && bisDatum.Text != Convert.ToString(date2.ToString("d")) || vonDatum.Text == Convert.ToString(date1.ToString("d")) && bisDatum.Text == Convert.ToString(date2.ToString("d"))) { var temp = ottoDataSetControlTableAdapter.GetDataBy(vonDatum.SelectedDate, bisDatum.SelectedDate);
List<MitarbeiterAnsichtCount> query = (from t in temp orderby t.packetDate select new MitarbeiterAnsichtCount ( t.ova, t.packet_list, t.packing, t.delivery_note, t.cardboard_labels, t.pallets, t.delivery_inside )).ToList();
foreach (MitarbeiterAnsichtCount i in query) { if (i.packetListEmployee != "") { if (!allpacketListEmployee.Contains(i.packetListEmployee)) { allpacketListEmployee[count] = i.packetListEmployee; count++; Array.Resize(ref allpacketListEmployee, allpacketListEmployee.Length + 1); } } if (i.packedUpEmployee != "") { if (!allpackedUpEmployee.Contains(i.packedUpEmployee)) { allpackedUpEmployee[count1] = i.packedUpEmployee; count1++; Array.Resize(ref allpackedUpEmployee, allpackedUpEmployee.Length + 1); } } if (i.deliveryNoteEmployee != "") { if (!alldeliveryNoteEmployee.Contains(i.deliveryNoteEmployee)) { alldeliveryNoteEmployee[count2] = i.deliveryNoteEmployee; count2++; Array.Resize(ref alldeliveryNoteEmployee, alldeliveryNoteEmployee.Length + 1); } } if (i.cardboardLabelsEmployee != "") { if (!allcardboardLabelsEmployee.Contains(i.cardboardLabelsEmployee)) { allcardboardLabelsEmployee[count3] = i.cardboardLabelsEmployee; count3++; Array.Resize(ref allcardboardLabelsEmployee, allcardboardLabelsEmployee.Length + 1); } } if (i.palletsEmployee != "") { if (!allpalletsEmployee.Contains(i.palletsEmployee)) { allpalletsEmployee[count4] = i.palletsEmployee; count4++; Array.Resize(ref allpalletsEmployee, allpalletsEmployee.Length + 1); } } if (i.deliveryInsideEmployee != "") { if (!alldeliveryInsideEmployee.Contains(i.deliveryInsideEmployee)) { alldeliveryInsideEmployee[count5] = i.deliveryInsideEmployee; count5++; Array.Resize(ref alldeliveryInsideEmployee, alldeliveryInsideEmployee.Length + 1); } } }
List<MitarbeiterAnsichtCount> employeeList2 = new List<MitarbeiterAnsichtCount>(); List<MitarbeiterAnsichtCount>[] employeeList3 = new List<MitarbeiterAnsichtCount>[count + count1 + count2 + count3 + count4 + count5 + count6];
for (int i = 0; i < count; i++) { employeeList3[i] = query.Where(x => x.packetListEmployee.Equals(allpacketListEmployee[i])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count - 1) { break; } } for (int i = count; i < count1 + count; i++) { employeeList3[i] = query.Where(x => x.packedUpEmployee.Equals(allpackedUpEmployee[i - count])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count1) { break; } } for (int i = count + count1; i < count2 + count1 + count; i++) { employeeList3[i] = query.Where(x => x.deliveryNoteEmployee.Equals(alldeliveryNoteEmployee[i - count - count1])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count2) { break; } } for (int i = count + count1 + count2; i < count3 + count2 + count1 + count; i++) { employeeList3[i] = query.Where(x => x.cardboardLabelsEmployee.Equals(allcardboardLabelsEmployee[i - count - count1 - count2])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count3) { break; } } for (int i = count + count1 + count2 + count3; i < count4 + count3 + count2 + count1 + count; i++) { employeeList3[i] = query.Where(x => x.palletsEmployee.Equals(allpalletsEmployee[i - count - count1 - count2 - count3])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count4) { break; } } for (int i = count + count1 + count2 + count3 + count4; i < count5 + count4 + count3 + count2 + count1 + count; i++) { employeeList3[i] = query.Where(x => x.deliveryInsideEmployee.Equals(alldeliveryInsideEmployee[i - count - count1 - count2 - count3 - count4])).ToList(); employeeList2.Add(new MitarbeiterAnsichtCount());
if (i == count5) { break; } }
for (int i = 0; i < employeeList3.Length; i++) { if (employeeList3[i] != null) { for (int j = 0; j < employeeList3[i].Count; j++) { if (i < count) { employeeList2[i].packetListEmployee = employeeList3[i][j].packetListEmployee; employeeList2[i].packetListCount++; } else if (i < count + count1) { employeeList2[i].packedUpEmployee = employeeList3[i][j].packedUpEmployee; employeeList2[i].packedUpCount++; } else if (i < count + count1 + count2) { employeeList2[i].deliveryNoteEmployee = employeeList3[i][j].packedUpEmployee; employeeList2[i].deliveryNoteCount++; } else if (i < count + count1 + count2 + count3) { employeeList2[i].cardboardLabelsEmployee = employeeList3[i][j].packedUpEmployee; employeeList2[i].cardboardLabelsCount++; } else if (i < count + count1 + count2 + count3 + count4) { employeeList2[i].palletsEmployee = employeeList3[i][j].packedUpEmployee; employeeList2[i].palletsCount++; } else if (i < count + count1 + count2 + count3 + count4 + count5) { employeeList2[i].packedUpEmployee = employeeList3[i][j].packedUpEmployee; employeeList2[i].packedUpCount++; } } } }
if (temp.Count > 0) { dataGrid.ItemsSource = null;
dataGrid.ItemsSource = employeeList2.OrderBy(x => x.packedUpEmployee); } else { MessageBox.Show("Es wurden keine Daten gefunden!", "Info!", MessageBoxButton.OK, MessageBoxImage.Information); } } else { MessageBox.Show("Datum Anzeige ist nicht korrekt!", "Achtung!", MessageBoxButton.OK, MessageBoxImage.Warning); } } |
So das Ergebnis sieht man im Dateianhang: Mitarbeiterübersicht.
Ich hätte noch zwei Fragen:
Wie könnte ich die Liste noch verändern das die gleichen Namen in einer reihe stehen ???
Vielleicht noch jemand eine Idee den Code kleiner zu halten ????
Danke schon mal
Einloggen, um Attachments anzusehen!
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 04.08.18 00:03
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: Chocoemilio
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 04.08.18 09:39
Da muß ich Frühlingsrolle recht geben, dein Code ist echt nicht gut (ich befürchte, daß du diesen auch noch für ein Produkt einsetzt - und nicht nur ein privates Projekt).
Zuersteinmal grobe design-technische Mängel:
- da du WPF benutzt, solltest du auch MVVM einsetzen (also ein passendes ViewModel verwenden und mittels eines Command anbinden)
- das Aufbereiten der Daten sollte in einer Logik-Klasse passieren (anscheinend hat euer Projekt keine vernünftige Architektur nach der gängigen 3-Schichten Architektur)!
Und nun noch einige konkrete Tipps zu deinem Code:
- der ganze Code ist viel zu lang für eine Methode (unterteile diese in kleinere Methoden, insbesondere da du immer wieder ähnlichen Code, z.B. bei den Schleifen, verwendest)
- eigene Mitarbeiterklasse
- verwende List<string> anstatt Arrays ( string[]) (weiter unten benutzt du diese ja auch - so brauchst du dich um das Vergrößern der Arrays nicht (mehr) zu kümmern)
- die "Aufzählung"-Schleife würde auch per LINQ umsetzbar sein
- die ganzen count-Berechnungen erscheinen mir auch optimierungsbedürftig
- ...
Wenn du den Code in einer eigenen Logik-Klasse untergebracht hast, so kannst du dann auch sehr einfach dafür einen Unit-Test schreiben, der dann die Korrektheit abprüft.
Für diesen Beitrag haben gedankt: Chocoemilio
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Fr 10.08.18 07:53
Hi
Ja danke, das der Code schlecht ist weiß ich, es musste nur schnell gehen und nach Hilfe gefragt hatte ich ja.
Das Projekt habe ich nicht geschrieben sondern übernommen und die haben kein MVVM verwendet, muss auch mit DataSet arbeiten. Ungewohnt auch für mich.
Alles umschreiben da fehlt die Zeit, würde lieber mit der Entity Frameworke arbeiten.
Ich möchte den Code auf jeden Fall noch verbessern.
Werde das beherzigen und danach melde ich mich nochmal.
Danke
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Fr 10.08.18 12:34
Hey
So habe den code jetzt verkleinert aber jetzt bin ich wieder an meinem Problem. Das Gruppieren mit Linq ????
Ein Name kann in jeder spalte vorhanden sein und diese sollen gruppiert werden, so wie die Anzahl der Zählung.
Alle gleichen Namen sollen in einer Zeile stehen.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| List<MitarbeiterLieferant> query1 = (from t in employeeList2 group t by new {t.packetListEmployee, t.packedUpEmployee, t.deliveryNoteEmployee, t.cardboardLabelsEmployee, t.palletsEmployee, t.deliveryInsideEmployee} into g select new MitarbeiterLieferant ( g.Key.packetListEmployee, g.Key.packedUpEmployee, g.Key.deliveryNoteEmployee, g.Key.cardboardLabelsEmployee, g.Key.palletsEmployee, g.Key.deliveryInsideEmployee )).ToList(); |
Weiter komme ich nicht und habe auch keine Ahnung wie ???
|
|
Chocoemilio
Beiträge: 38
|
Verfasst: Mo 13.08.18 12:32
Hi
Habe das jetzt so gelöst, der Alte Quellcode ist weg und dafür habe ich eine Stored-Procedure geschrieben.
Wollte das eigentlich mit linq machen. Mache ich auch noch
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| SELECT `name`, (SELECT COUNT(packet_list) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`packet_list` AND packetDate BETWEEN date_from AND date_to) packet_list, (SELECT COUNT(packing) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`packing` AND packingDate BETWEEN date_from AND date_to) packing, (SELECT COUNT(delivery_note) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`delivery_note` AND deliveryNoteDate BETWEEN date_from AND date_to) delivery_note, (SELECT COUNT(cardboard_labels) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`cardboard_labels` AND cardbordLabelsDate BETWEEN date_from AND date_to) cardboard_labels, (SELECT COUNT(pallets) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`pallets` AND palletsDate BETWEEN date_from AND date_to) pallets, (SELECT COUNT(delivery_inside) FROM Otto.OttoTool_Control oc WHERE u.`name` = oc.`delivery_inside` AND deliveryInsideDate BETWEEN date_from AND date_to) delivery_inside FROM AzManager.Users u LEFT JOIN Otto.OttoTool_Control oc ON oc.packet_list = u.name WHERE (allow_fbatool_packing = 'Y' OR allow_fbatool_printing = 'Y' OR allow_fbatool_labeling = 'Y') GROUP BY u.name ORDER BY u.`name`; |
Moderiert von Th69: C#- durch SQL-Tags ersetzt
|
|