Ich verwende Entity Framework, um ein Rastersteuerelement zu füllen. Manchmal, wenn ich Updates mache, erhalte ich die folgende Fehlermeldung:
Die Anweisung zum Speichern, Einfügen oder Löschen des Speichers hat eine unerwartete Anzahl von Zeilen (0) beeinflusst. Entitäten wurden möglicherweise geändert oder gelöscht, seit Entitäten geladen wurden. Aktualisieren Sie ObjectStateManager-Einträge.
Ich kann nicht herausfinden, wie ich das reproduzieren soll. Aber es könnte etwas damit zu tun haben, wie nahe ich die Updates mache. Hat jemand dies gesehen oder weiß jemand, worauf sich die Fehlermeldung bezieht?
Bearbeiten: Leider kann ich das Problem, das ich hier hatte, nicht mehr reproduzieren, da ich mich von diesem Projekt zurückgezogen habe und mich nicht erinnere, ob ich irgendwann eine Lösung gefunden habe, ob ein anderer Entwickler sie behoben hat oder ob ich sie umgangen habe. Daher kann ich keine Antworten akzeptieren.
quelle
Request.Uri
Sie sich die tatsächliche Anforderungs-URL an. In meinem Fall hatte ich eine Tracking-Logik, die meine Site traf und den Kontext unnötig aus der Datenbank lud (und gelegentlich auch aktualisierte). Auf der eigentlichen Seite, die ich debuggte, wurden die Daten von einer dummen Tracking-Code-Logik erfasst.Antworten:
Dies ist ein Nebeneffekt einer Funktion, die als optimistische Parallelität bezeichnet wird.
Sie sind sich nicht 100% sicher, wie Sie es in Entity Framework ein- oder ausschalten sollen, aber im Grunde sagt es Ihnen, dass zwischen dem Zeitpunkt, an dem Sie die Daten aus der Datenbank abgerufen haben, und dem Zeitpunkt, an dem Sie Ihre Änderungen gespeichert haben, jemand anderes die Daten geändert hat (was bedeutete, dass Sie gegangen sind um es zu speichern 0 Zeilen wurden tatsächlich aktualisiert). In SQL-Begriffen ist ihre
update
Abfragewhere
enthält die Klausel den ursprünglichen Wert jedes Felds in der Zeile. Wenn 0 Zeilen betroffen sind, weiß sie, dass ein Fehler aufgetreten ist.Die Idee dahinter ist, dass Sie am Ende keine Änderung überschreiben, von der Ihre Anwendung nicht wusste, dass sie stattgefunden hat - es ist im Grunde eine kleine Sicherheitsmaßnahme, die .NET bei all Ihren Updates eingeführt hat.
Wenn es konsistent ist, besteht die Wahrscheinlichkeit, dass es innerhalb Ihrer eigenen Logik geschieht (z. B. Sie aktualisieren die Daten tatsächlich selbst in einer anderen Methode zwischen der Auswahl und dem Update), aber es könnte einfach eine Race-Bedingung zwischen zwei Anwendungen sein.
quelle
Ich bin darauf gestoßen und es wurde dadurch verursacht, dass das ID-Feld (Schlüsselfeld) der Entität nicht festgelegt wurde. Wenn der Kontext zum Speichern der Daten verwendet wurde, konnte er keine ID = 0 finden. Stellen Sie sicher, dass in Ihrer Aktualisierungsanweisung ein Haltepunkt eingefügt ist, und überprüfen Sie, ob die ID der Entität festgelegt wurde.
Aus Paul Belloras Kommentar
quelle
Wow, viele Antworten, aber ich habe diesen Fehler bekommen, als ich etwas etwas anderes gemacht habe, das noch niemand erwähnt hat.
Kurz gesagt, wenn Sie ein neues Objekt erstellen und EF mitteilen, dass es mit dem geändert wurde,
EntityState.Modified
wird dieser Fehler ausgegeben, da er noch nicht in der Datenbank vorhanden ist. Hier ist mein Code:Ja, das scheint dumm zu sein, aber es ist entstanden, weil die fragliche Methode
foo
, die früher an sie übergeben wurde, früher erstellt wurde, jetzt nur nochsomeValue
an sie übergeben wurde und sichfoo
selbst erstellt .Einfache Lösung, gerade Änderung
EntityState.Modified
zuEntityState.Added
ändern oder die ganze Linie an:quelle
Ich hatte den gleichen erschreckenden Fehler ... :) Dann wurde mir klar, dass ich vergaß, einen zu setzen
@Html.HiddenFor(model => model.UserProfile.UserId)
für den Primärschlüssel des zu aktualisierenden Objekts! Ich neige dazu, dieses einfache, aber sehr wichtige Ding zu vergessen!
Übrigens:
HiddenFor
ist für ASP.NET MVC.quelle
UserId
in der Form zu speichern , sehr anfällig für Hacker ... dies sollte später vonHttpContext.Current.User.Identity.Name
HiddenFor
Sie esHttpContext
sowieso benötigen ... Ich würde diese Eigenschaft überhaupt nicht in das Formular einfügen, was mich zwingen würde, sie immer serverseitig zu füllen ...Überprüfen Sie, ob Sie das Attribut "DataKeyNames" in der GridView vergessen haben. Dies ist ein Muss beim Ändern von Daten in GridView
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
quelle
Das Problem wird durch eines von zwei Dingen verursacht:
Concurrency Mode: Fixed
. Die optimistische Parallelität hat verhindert, dass die Daten gespeichert werden. Dh. Einige haben die Zeilendaten zwischen dem Zeitpunkt des Empfangs der Serverdaten und dem Speichern Ihrer Serverdaten geändert.StoreGeneratedPattern = Computed
) und diese Zeile nicht vorhanden ist.quelle
Ich habe den gleichen Fehler erhalten, weil ein Teil der PK eine datetime-Spalte war und der eingefügte Datensatz DateTime.Now als Wert für diese Spalte verwendete. Das Entitätsframework fügt den Wert mit Millisekundengenauigkeit ein und sucht dann nach dem Wert, den es gerade eingefügt hat, auch mit Millisekundengenauigkeit. SqlServer hatte den Wert jedoch auf die zweite Genauigkeit gerundet, sodass das Entity-Framework den Millisekunden-Genauigkeitswert nicht finden konnte.
Die Lösung bestand darin, die Millisekunden von DateTime.Now vor dem Einfügen abzuschneiden.
quelle
Date
Spalte mit einemDateTime
WertIch hatte das gleiche Problem und die Antwort von @ webtrifusion half, die Lösung zu finden.
Mein Modell verwendete das
Bind(Exclude)
Attribut für die ID der Entität, wodurch der Wert der ID der Entität in HttpPost Null war.quelle
Ich hatte das gleiche Problem, ich finde heraus, dass es durch die RowVersion verursacht wurde, die null war. Überprüfen Sie, ob Ihre ID und Ihr RowVersion sind nicht null .
Weitere Informationen finden Sie in diesem Tutorial
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
quelle
Ich bekam diesen Fehler, nachdem ich von Modell zuerst zu Code zuerst gewechselt hatte. Ich habe mehrere Threads, die eine Datenbank aktualisieren, wobei einige möglicherweise dieselbe Zeile aktualisieren. Ich weiß nicht, warum ich bei der Verwendung von model-first kein Problem hatte. Nehmen Sie an, dass ein anderer Standard für die Parallelität verwendet wird.
Um es an einem Ort zu handhaben und die Bedingungen zu kennen, unter denen es auftreten könnte, habe ich meiner DbContext-Klasse die folgende Überladung hinzugefügt:
Dann
SaveChanges(true)
wo immer möglich angerufen .quelle
Sie müssen explizit ein BoundField des Primärschlüssels einfügen. Wenn Sie nicht möchten, dass der Benutzer den Primärschlüssel sieht, müssen Sie ihn über CSS ausblenden:
Wobei 'versteckt' eine Klasse in CSS ist, deren Anzeige auf 'keine' gesetzt ist.
quelle
Fügen Sie während der Bearbeitung die ID oder den Primärschlüssel der Entität als verstecktes Feld in die Ansicht ein
dh
das löst das Problem.
Wenn Ihr Modell nicht verwendete Elemente enthält, schließen Sie diese ebenfalls ein und senden Sie sie an den Controller
quelle
Ich bin auch auf diesen Fehler gestoßen. Das Problem wurde durch einen Trigger auf dem Tisch verursacht, auf dem ich speichern wollte. Der Trigger verwendete 'INSTEAD OF INSERT', was bedeutet, dass 0 Zeilen jemals in diese Tabelle eingefügt wurden, daher der Fehler. Glücklicherweise war die Triggerfunktion in einigen Fällen falsch, aber ich denke, es könnte sich um eine gültige Operation handeln, die irgendwie im Code behandelt werden sollte. Hoffe das hilft jemandem eines Tages.
quelle
SELECT SCOPE_IDENTITY() as MyViewId
Ich bin auf dieses Problem in einer Tabelle gestoßen, in der ein Primärschlüssel fehlte und die eine DATETIME (2, 3) -Spalte hatte (der "Primärschlüssel" der Entität war also eine Kombination aller Spalten) ... Beim Ausführen des Einfügens hatte der Zeitstempel Eine genauere Zeit (2018-03-20 08: 29: 51.8319154), die auf (2018-03-20 08: 29: 51.832) gekürzt wurde, sodass die Suche in Schlüsselfeldern fehlschlägt.
quelle
Ich hatte auch diesen Fehler. Es gibt Situationen, in denen die Entität möglicherweise nicht über den tatsächlich verwendeten Datenbankkontext informiert ist oder das Modell möglicherweise anders ist. Stellen Sie dazu Folgendes ein: EntityState.Modified; zu EntityState.Added;
Um dies zu tun:
Dadurch wird sichergestellt, dass die Entität weiß, dass Sie den Status verwenden oder hinzufügen, mit dem Sie arbeiten. Zu diesem Zeitpunkt müssen alle richtigen Modellwerte eingestellt werden. Achten Sie darauf, keine Änderungen zu verlieren, die möglicherweise im Hintergrund vorgenommen wurden.
Hoffe das hilft.
quelle
Meine Zeilenversion war null und musste daher der Ansicht hinzugefügt werden, die mein Problem gelöst hat
quelle
Die Linie
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
hat in meinem Fall den Trick gemacht:quelle
Stellen Sie einfach sicher, dass in Tabelle und Formular sowohl der Primärschlüssel als auch edmx aktualisiert sind.
ich fand , dass Fehler während der Aktualisierung waren in der Regel wegen: - kein Primärschlüssel in der Tabelle - kein Primärschlüssel in der Bearbeitungsansicht / Form (zB
@Html.HiddenFor(m=>m.Id
)quelle
Ich hatte das gleiche Problem. In meinem Fall habe ich versucht, den Primärschlüssel zu aktualisieren, was nicht zulässig ist.
quelle
Ich habe diesen Fehler sporadisch bei der Verwendung eines
async
Methode erhalten. Ist nicht passiert, seit ich zu einer synchronen Methode gewechselt bin.Sporadisch Fehler:
Funktioniert die ganze Zeit:
quelle
Ich habe diesen Fehler erhalten, als ich einige Zeilen in der Datenbank (in der Schleife) gelöscht und die neuen in derselben Tabelle hinzugefügt habe.
Die Lösung für mich bestand darin, in jeder Schleifeniteration dynamisch einen neuen Kontext zu erstellen
quelle
quelle
Dies ist auch der Fall, wenn Sie versuchen, eine eindeutige Einschränkungssituation einzufügen. Wenn Sie also nur einen Adresstyp pro Arbeitgeber haben können und versuchen, einen zweiten Adresstyp mit demselben Arbeitgeber einzufügen, tritt das gleiche Problem auf .
ODER
Dies kann auch passieren, wenn allen zugewiesenen Objekteigenschaften dieselben Werte wie zuvor zugewiesen wurden.
quelle
Wenn Sie versuchen, in Ihrer edmx-Datei eine Zuordnung zu einer "Funktion Imports" zu erstellen, kann dies zu diesem Fehler führen. Löschen Sie einfach die Felder zum Einfügen, Aktualisieren und Löschen in den Zuordnungsdetails für eine bestimmte Entität in Ihrem edmx, und es sollte funktionieren. Ich hoffe ich habe es klar gemacht.
quelle
Ich habe diese Ausnahme beim Anhängen eines Objekts erhalten, das nicht in der Datenbank vorhanden war. Ich hatte angenommen, dass das Objekt aus einem separaten Kontext geladen wurde, aber wenn der Benutzer die Site zum ersten Mal besuchte, wurde das Objekt von Grund auf neu erstellt. Wir haben automatisch inkrementierende Primärschlüssel, damit ich sie ersetzen kann
mit
quelle
Nun, ich habe das gleiche Problem. Aber das lag an meinem eigenen Fehler. Eigentlich habe ich ein Objekt gespeichert, anstatt es hinzuzufügen. Das war also der Konflikt.
quelle
Eine Möglichkeit, dieses Problem in einer SQL Server-Umgebung zu beheben, besteht darin, den in Ihrer SqlServer-Kopie enthaltenen SQL-Profiler zu verwenden. Wenn Sie die Express-Version verwenden, erhalten Sie eine kostenlose Kopie von Express Profiler von CodePlex über den folgenden Link:
Express Profiler
Mit Sql Profiler können Sie auf alles zugreifen, was von EF an die DB gesendet wird. In meinem Fall betrug dies:
Ich habe dies in ein Abfragefenster in SQL Server eingefügt und ausgeführt. Sicher genug, obwohl es lief, waren 0 Datensätze von dieser Abfrage betroffen, daher wurde der Fehler von EF zurückgegeben.
In meinem Fall wurde das Problem durch die CategoryID verursacht.
Es wurde keine CategoryID durch die an die Datenbank gesendete ID EF identifiziert, sodass 0 Datensätze betroffen sind.
Dies war jedoch nicht die Schuld von EF, sondern ein fehlerhafter Null-Koaleszenz "??" Anweisung in einem View Controller, der Unsinn an die Datenebene gesendet hat.
quelle
Keine der obigen Antworten deckte meine Situation und die Lösung dafür ab.
Code, bei dem der Fehler im MVC5-Controller ausgelöst wurde:
Ich habe diese Ausnahme erhalten, als ich ein Objekt aus einer Bearbeitungsansicht gespeichert habe. Der Grund dafür war, dass ich beim Zurückkehren zum Speichern die Eigenschaften geändert hatte, die den Primärschlüssel für das Objekt bildeten. Daher machte es für EF keinen Sinn, den Status auf "Geändert" zu setzen - es war ein neuer Eintrag, kein zuvor gespeicherter.
Sie können dies lösen, indem Sie entweder A) den Aufruf zum Speichern ändern, um das Objekt hinzuzufügen, oder B) den Primärschlüssel beim Bearbeiten einfach nicht ändern. Ich habe B).
quelle
Als in der akzeptierten Antwort stand, dass eine Änderung, von der Ihre Anwendung nicht wusste, dass sie stattgefunden hat , nicht überschrieben wird , war ich skeptisch, weil mein Objekt neu erstellt wurde. Aber dann stellte sich heraus, dass es eine gab
INSTEAD OF UPDATE, INSERT- TRIGGER
an die Tabelle Anhang angehängt war, der eine berechnete Spalte derselben Tabelle aktualisierte.Sobald ich dies geändert habe,
AFTER INSERT, UPDATE
hat es gut funktioniert.quelle
Dies geschah mir aufgrund einer Nichtübereinstimmung zwischen datetime und datetime2. Seltsamerweise funktionierte es gut, bevor ein Tester das Problem entdeckte. Mein Code First-Modell enthielt eine DateTime als Teil des Primärschlüssels:
Die generierte Spalte ist eine Datums- / Uhrzeitspalte. Beim Aufrufen von SaveChanges hat EF die folgende SQL generiert:
Da versucht wurde, eine datetime-Spalte mit einem datetime2-Wert abzugleichen, wurden keine Ergebnisse zurückgegeben. Die einzige Lösung, die ich mir vorstellen konnte, war, die Spalte in datetime2 zu ändern:
quelle
datetime
vs. zu tundatetime2
. Im Wesentlichen werden einige Millisekundenwerte zu einer Übereinstimmung ausgewertet, andere nicht. Das gleiche passierte mir und ich wechselte auch zuDateTime2
.