Wir haben eine Web MVC .NET-Anwendung, die den ersten Codeansatz verwendet. Bei der Durchführung grundlegender CRUD-Vorgänge verhält sich alles normal, aber unsere Berichte und Aufgaben mit langer Laufzeit dauern ewig..Net C# -Anwendung - Korrekte Methode zur Lösung von Leistungsproblemen im Zusammenhang mit Änderungsnachverfolgung im Entitätsframework
Die meisten unserer problematischen Fällen kann durch die folgenden zwei Szenarien wieder aufgenommen werden:
- Es ist eine Aufgabe, die iteriert auf 10.000+ Artikel (mit
sqlDataReader
), ein paar Änderungen vornimmt und erstellt eine Kopie für jeden von ihnen. - Wir haben Berichte, die auf 100.000 Elemente (unter Verwendung
sqlDataReader
) iteriert, um einige Informationen zu lesen und in eine Datei zu schreiben. in Entity Framework Änderungsverfolgung:
Nach der Realisierung, dass die Zeit, um unsere Aufgaben zu verarbeiten erforderlich und Berichte wuchsen exponentiell (O(n^2)
) mit der Anzahl der Elemente, die Wurzel des Problems zu verarbeiten, untersuchten wir weiter und fanden heraus.
Alles funktioniert gut, wenn wir AutoDetectChangesEnabled
deaktivieren, aber jeder Artikel, den wir zu diesem Thema gelesen haben, sagt, wir sollten dies vermeiden, wann immer es möglich ist.
Also hier ist meine Frage: Deaktiviert AutoDetectChangesEnabled
die einzige oder die empfohlene Art der Lösung dieser Art von Problemen? Gibt es eine andere saubere Lösung? Wie würdest du das angehen?
Das setzt voraus, wir all Empfehlungen in dieser Serie von Artikeln erwähnt würden folgen: https://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/
Hier ein kleines Codebeispiel 2 darstellt Szenario:
//SQL query to fetch 100,000+ items
SqlCommand command = new SqlCommand(query, conn);
//Use SqlDataReader to stream results
using (SqlDataReader reader = command.ExecuteReader())
{
/*In the following loop, if we use SqlCommand instead of LINQ, it's fast and steady.
But as soon as we start using LINQ, each iteration takes exponentially more time
to complete - even if we are only making read operations. Unless we disable
AutoDetectChangesEnabled: then it's fast and steady.*/
while (reader.Read())
{
/*Fetch additional information. I know this could be done with a join in the
original query but we have a lot of additional info to fetch and the query would
be too heavy (this is a simplified version of the code).*/
Item item = db.Items.Where(x => x.OtherItem_Id == (int)reader["Id"]).FirstOrDefault();
//Read properties
prop1 = item.prop1;
prop2 = item.prop2;
prop3 = item.prop3;
//Use those properties to add an entry to a csv file
}
}
Dank!
Sie rufen hier eine sehr breite Frage zu stellen, gibt es keine eine Möglichkeit, zu debuggen oder das Performance-Problem lösen Sie sind Performance-Probleme sind immer sehr schwierig zu beheben und immer eine Vielzahl von möglichen Lösungen –
Sie können nur sagen, weg von AutoDetectChanges zu deaktivieren, da ich denke, dass EF könnte nicht wissen, welche Datensätze sind schmutzig auf SaveChanges, obwohl ich sein könnte falsch, nur eine Vermutung, habe nicht mit EF in einer Weile gearbeitet –
Es kann richtig gemacht werden (zB mit der Eigenschaft API, um Felder zu aktualisieren), aber ich stimme zu, es ist nicht etwas, das sollte wenn möglich deaktiviert werden. Deshalb frage ich die Meinung der Community hier. Ich werde ein Beispiel veröffentlichen, damit Sie eine bessere Idee haben können. – Alexandre