Hallo zusammen, ich fülle eine DataGridview und möchte anschließend zwei Spalten farbig markieren.
Soweit klappt das auch alles. Der Aufruf zum Laden/Anzeigen der Daten geht richtig schnell, nur die farbliche Markierung dauert recht lange (~10sek).
Nun wäre meine Frage, ob ein anderer Aufbau zu einer Verbesserung der Performance führt? Bzw. was ich ändern kann/soll?
dataGridView1.DataSource = dt;
Die farbliche Markierung:
void ColorGridView()
{
bool weKomplettAbgeschlossen = false;
bool weTeilweiseAbgeschlossen = false;
bool reKomplettAbgeschlossen = false;
bool reTeilweiseAbgeschlossen = false;
for (int n = 0; n < dataGridView1.Rows.Count; n++)
{
// Prüfen ob WEbereits komplett abgeschlossen wurde.
weKomplettAbgeschlossen = AufrufWE_Abgeschlossen_Pruefen(Convert.ToInt32(dataGridView1["id", n].Value));
if (!weKomplettAbgeschlossen)
{
weTeilweiseAbgeschlossen = AufrufWE_Erfolgt(Convert.ToInt32(dataGridView1["id", n].Value));
if (weTeilweiseAbgeschlossen)
{
dataGridView1["WEabgeschlossen", n].Style.BackColor = System.Drawing.Color.Yellow;
}
if (!weTeilweiseAbgeschlossen)
{
dataGridView1["WEabgeschlossen", n].Style.BackColor = System.Drawing.Color.Red;
}
}
if (weKomplettAbgeschlossen)
{
dataGridView1["WEabgeschlossen", n].Style.BackColor = System.Drawing.Color.Green;
}
// Prüfen RE komplett abgeschlossen.
reKomplettAbgeschlossen = AufrufRE_Abgeschlossen_Pruefen(Convert.ToInt32(dataGridView1["id", n].Value));
if (!reKomplettAbgeschlossen)
{
reTeilweiseAbgeschlossen = AufrufRE_Erfolgt(Convert.ToInt32(dataGridView1["id", n].Value));
if (reTeilweiseAbgeschlossen)
{
dataGridView1["REabgeschlossen", n].Style.BackColor = System.Drawing.Color.Yellow;
}
if (!reTeilweiseAbgeschlossen)
{
dataGridView1["REabgeschlossen", n].Style.BackColor = System.Drawing.Color.Red;
}
}
if (reKomplettAbgeschlossen)
{
dataGridView1["REabgeschlossen", n].Style.BackColor = System.Drawing.Color.Green;
}
}
}
Hier mal der Aufruf AufrufWE_Erfolgt:
public static bool AufrufWE_Erfolgt(int id)
{
try
{
using (entity ctx = new entity())
{
var query = (from w in ctx.tblwareneingang
where w.bestellId == id
select w).ToList();
if (query != null)
{
foreach (tblwareneingang we in query)
{
// falls abgeschlossen.
if (we.liefermengeAbgeschlossen)
return true;
else
// falls zumindest Eintrag existiert.
if (we.gelieferteMenge != 0)
return true;
}
return false;
}
else
return false;
}
}
catch (Exception ex)
{
return false; ;
}
}
Der Code ist im Endeffekt das, was man weitläufig Spaghetti-Code nennt.
Daher ja: da kann man enorm viel verbessern.
Enorm fressen wird der Datenbank Code. Da ist quasi alles falsch, was man falsch machen kann 🙂
Im Endeffekt vollständig Code neu schreiben:
Das sollte das ganze um 99+% verbessern und in wenigen Millisekunden durchlaufen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Abt danke für deine Hilfe!
Ich werde mich mal an die Überarbeitung machen ...
- Daten in einem Rutsch holen, nicht in n
Verstehe zwar was du damit meinst, aber wie soll es in einem Rutsch gehen? Die Daten schon beim ersten Abruf mit übergeben?
Sonst kann ich doch nur zeilenweise prüfen?!
Das bekommt man fast geschenkt, wenn man Datenbindung verwendet 🙂Bind data to DataGridView Control - Windows Forms .NET Framework
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Du könntest deine Abfrage auch durch ein Dictioanry mit der ID als Key und dem Bool als Value umstellen.
Dazu müsstest du alle Daten vorladen und pro ID aus den Daten dann deine Logik zur Prüfung durchführen.
Dann kannst du einfach mit TryGetValue den Bool Wert ermitteln.
Gibt TryGetValue zurück, müsst du dann nur den Fall wie bei einem false verarbeiten.
Dadurch sparst du dir auch die Einzelabfragen, die am meisten Performance kosten.
Ansonsten ist der Code, wie Abt auch schon schrieb, stark verbesserungswürdig.
Alleine deine if Verzweigungen mit Negierung sind einfach else Blöcke.
Aber auch die anderen Anmerkungen von Abt sollest du beachten um den Code in Nahe Zukunft noch sinnvoll warten zu können.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
..und noch eine Vorgehensweise (die beim Laden von Internetseiten Sinn haben kann): erst das Control überhaupt darstellen lassen, danach in der gewünschten Formatierung.
Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉
Die statische Methode sieht nun so aus:
...
foreach (var item in lst)
{
var query = (from w in ctx.tblwareneingang
where w.Id == item
select new EinkaufDaten
{
Id = (int)w.bestellungen_ekId,
LiefermengeAbgeschlossen = w.liefermengeAbgeschlossen,
GelieferteMenge = (int)w.gelieferteMenge
}).ToList();
lstDaten.AddRange(query);
}
return lstDaten;
...
Ich habe nun die Methode ColorGridView wie folgt umgebaut.
void ColorGridView(DataGridView dg, List<string> lst)
{
List<EinkaufDaten> lstDaten = DB.WE_Erfolgt(lst);
foreach (var item in lstDaten)
{
foreach (DataGridViewRow row in dg.Rows)
{
if (row.Cells["id"].Value.ToString() == item.IdEK.ToString())
{
if ((item.MengeAbgeschlossen == true) || (item.GelieferteMenge > 0))
{
row.Cells["WEabgeschlossen"].Style.BackColor = System.Drawing.Color.Yellow;
}
else
{ row.Cells["WEabgeschlossen"].Style.BackColor = System.Drawing.Color.Red; }
}
}
Hoffe, dass dies nun zumindest etwas besser ist?!
Abruf der Daten erfolgt nur einmalig über DB.WE_Erfolgt.
Momentan ist es auch deutlich schneller. Es wird auch farblich markiert, aber der else Zweig für dir rote Farbe wird nie
ausgeführt. Weshalb?
Naja, aus unserer Sicht stellt sich die Frage, was Du hören willst.
Die "So programmiert man halt in Objektorientierten Sprachen / C# / .NET / WinForms / Desktop Apps / Software Entwicklung nicht" hast Du weiter oben ja schon passiv erhalten, wie man das eigentlich umsetzen würde.
Gemacht hast das ja nicht, ist ja weiterhin statisch orientierter Spaghetti Code. Wenn Du das so behalten willst; tjo, dann ist das eben so, wird auch irgendwie schon funktionieren, aber dann bleibt halt auch der Code auf dem Level.
Weiß also nicht, was Du für eine Antwort Dir wünscht, wenn das eigentlich ja weiter oben schon steht 🙂
Es wird auch farblich markiert, aber der else Zweig für dir rote Farbe wird nie
ausgeführt. Weshalb?
Wir haben leider auch keine Glaskugel, aber deswegen gibts den Debugger.
[Artikel] Debugger: Wie verwende ich den von Visual Studio?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Verstanden hab ich es ... hab aber eine schnelle Umsetzung gebraucht.
ABER ich arbeite mich jetzt in Repository Pattern ein.