Folgendes Code-Beispiel zeigt, wie man den Fehler Failed executing DbCommand Update in Asp.Net Core und EF Entity Framework lösen kann.
Aufgabe: meine Asp.Net Core 2 MVC Anwendung hÀngt sich regelmÀssig auf, wenn ein Datensatz geschrieben werden soll.
Dabei handelt es sich um einen einfachen ZÀhler, der die Webseiten zugriffe erhöht.
Die Fehlermeldung in der Log-Datei der Asp Core Anwendung lautet:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (45ms) [Parameters=[@p1='?', @p0='?'], CommandType='Text', CommandTimeout='30'] .. UPDATE [tbl_Notes] SET .. System.Data.SqlClient.SqlException (0x80131904): Timeout expired. |
Und hierzu kommt auch der Fehler:
fail: Microsoft.EntityFrameworkCore.Update[10000] An exception occurred in the database while saving changes for context type |
Log-Datei der Asp Anwendung
Fehler-Auszug, wo der Code hÀngen bleibt.
1: Update eines Datensatzes
fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (45ms) [Parameters=[@p1='?', @p0='?'], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [tbl_Notes] SET [sumViews] = @p0 WHERE [IDNote] = @p1; SELECT @@ROWCOUNT; System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): Der Wartevorgang wurde abgebrochen at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__108_0(Task`1 result) |
2.Update eines Datensatzes
Error Number:-2,State:0,Class:11 fail: Microsoft.EntityFrameworkCore.Update[10000] An exception occurred in the database while saving changes for context type 'Readdy.Data.ApplicationDbContext'. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen |
Auszug zur Fehlerquelle in den Source-Dateien:
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Counter_Logger.<counter_of_View_erhoehen>d__0.MoveNext() in D:\Programmierung\Web\Readdy\Readdy\Readdy\_classes\Counter_Logger.cs:line 21 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Readdy.Controllers.NotesController.<Details>d__6.MoveNext() in D:\Programmierung\Web\Readdy\Readdy\Readdy\Controllers\NotesController.cs:line 322 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() |
Lösung:
Man kann einfache Speicher-VorgÀnge mit AcceptAllChanges erzwingen.
Hierzu muss man den Save-Parameter: AcceptAllChanges in Entity Framework auf True setzen
await EF_Model.dbContext.SaveChangesAsync(true); |
C# Code-Beispiel mit Asp.Net Core 2 und Entity Framework.
ErlÀuterung.
WÀhrend die Methode Daten abholt, und Àndert, kann es sein dass der Datensatz von einer anderen Seite geöffnet wird.
Deshalb reicht bei einfachen ZĂ€hlern und nicht redundanden Loggern das einfache Speichern ohne Transaction-PrĂŒfung
public static async Task<int?> counter_of_View_erhoehen(long IDUser, long IDNote = 0) { //-------------< logViewCounter_erhoehen() >------------- //< Sum ViewLogs > NoteModel note = await EF_Model.dbContext.tbl_Notes.SingleOrDefaultAsync(m => m.IDNote == IDNote); if (note == null) return 0;
if (note.sumViews == null) note.sumViews = 0; note.sumViews += 1; await EF_Model.dbContext.SaveChangesAsync(true); //</ Sum ViewLogs >
return note.sumViews; //-------------</ logViewCounter_erhoehen() >------------- } |
Screenshot
IM Code einfach den Parameter (true) einfĂŒgen um das Speichern zu erzwingen