webentwicklung-frage-antwort-db.com.de

Die Anweisung zum Aktualisieren, Einfügen oder Löschen des Speichers beeinflusste eine unerwartete Anzahl von Zeilen (0) EntityFramework

Ich erhalte die folgende Fehlermeldung, wenn ich versuche, Änderungen an einem Kontext zu speichern: 

Die Anweisung zum Aktualisieren, Einfügen oder Löschen des Speichers hat ein unerwartetes Ergebnis betroffen Anzahl der Zeilen (0). Entitäten wurden möglicherweise seit .__ geändert oder gelöscht. Entitäten wurden geladen. Aktualisieren Sie die ObjectStateManager-Einträge.

Ich habe folgende Klassen:

Person

public class Person : IPerson
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Name
    {
        get
        {
            return FirstName + " " + LastName;
        }
        set{}
    }

    public string Email { get; set; }
    public DateTime? LastModified { get; set; }
    public virtual ICollection<Result> Results { get; set; }
}

Benutzerprofil

public class UserProfile : Person
{
    public UserProfile()
    {
        Faculty = new Faculty();
        Projects = new Collection<Project>();
        Results = new Collection<Result>();
    }
    public string UserName { get; set; }
    public string CNP { get; set; }
    public virtual Faculty Faculty { get; set; }
    public virtual ICollection<Project> Projects { get; set; }
}

Ergebnis

public abstract class Result:INamedEntity
{
    protected Result()
    {
        ResultType = new ResultType();
    }
    public int Id { get; set; }
    public string Name{get;set;}
    public virtual ResultType ResultType { get; set; }
    public virtual ICollection<Person> People { get; set; }
    public DateTime? LastModified { get; set; }
}

Nachdem ich dem Kontext einen Wert hinzugefügt habe:

_ctx.Users.Single(u => u.Id == userId).Results.Add(result);

Ich erhalte die Fehlermeldung, wenn ich _ctx.SaveChanges() anrufe.

Meine Funktion wurde aktualisiert zu:

public bool Save()
{

    try
    {
        _ctx.SaveChanges();
    }
    catch (OptimisticConcurrencyException)
    {
        ((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Users);
        ((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Results);
        _ctx.SaveChanges();
    }
    return true;
}

Aber der Fehler ist nicht aufgefangen ... Danke

22
trebor

Das Problem bestand darin, dass zwei von uns an diesem Projekt arbeiten und mein Kollege seine eigene Instanz von DBContext erstellt hat. Für wen auch immer dieses Problem in der Zukunft hat, stellen Sie sicher, dass Sie nicht zwei verschiedene Instanzen Ihrer DBContext gleichzeitig haben

13
trebor

Fügen Sie dies Ihrer edit.cshtml hinzu

@Html.HiddenFor(model => model.Id)

Ich hatte dieses Problem und stellte fest, dass die ID als 0 angezeigt wurde, da sie nicht auf der Seite war.

Ich habe dies auch auf meinem ViewModel (ich verwende den View-Model-Ansatz)

[HiddenInput(DisplayValue = false)]
[Key]
public int Id { get; set; }
40
VoltaicShock

Ihre Ausnahme bedeutet, dass Ihre Daten zwischen dem Zeitpunkt, zu dem Sie Daten aus der Datenbank abgerufen und geändert haben, geändert wurden.

Standardmäßig implementiert das Entity Framework ein optimistisches Parallelitätsmodell. Dies bedeutet, dass zwischen den Abfragen der Daten und dem Aktualisieren der Daten keine Sperren für Daten in der Datenquelle gehalten werden. MSDN

so verwalten Sie Parallelität in einem Objektkontext . MSDN

Oder folgen Sie dieser Antwort, die den Kontext auffrischt. Paketüberfluss

2
Suraj Singh

Für mich war das Problem, dass ich die action Bindings nicht richtig gesetzt hatte:

public ActionResult Edit([Bind(Include = "VehicleID,Name,CreateDate,PowerPS,DrivenKM")] Car car)
    { ... }

Die VehicleID wurde mit der falschen Kennung zugeordnet. Daher erhielt Entity Framework immer 0 als Primärschlüssel.

2
Thomas

Wenn Sie jemals auf dieses Problem gestoßen sind und keine der oben genannten Lösungen Ihnen geholfen hat, können Sie dies vielleicht versuchen. Ich hatte auch dieses seltsame Problem, und die Art und Weise, wie ich es beheben konnte, ist, dass ich ein Feld auf Primärschlüssel gesetzt habe und es automatisch erhöhen oder auf Identität setzen habe. Angenommen, Sie haben die Person-Tabelle und möglicherweise eine personID, setzen Sie sie auf Primärschlüssel und stellen Sie sicher, dass sie automatisch inkrementiert wird.

1
Clyde

fügen Sie meiner DbContext-Klasse die folgende Überladung hinzu:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

Dann wird SaveChanges(true) aufgerufen, wo immer dies möglich ist.

1

Ich bin auch auf diese Fehlermeldung gestoßen. Die Ursache meines Fehlers waren Primär-/Fremdschlüsselkonflikte. Ich hatte einige neue Daten in meine Datenbank eingefügt und meine Fremdschlüsselwerte waren deaktiviert (Fehler in meinem Upload-Skript). 

Verwenden Sie SQL Profiler, um das fehlerhafte Einfügungsskript aufzuspüren. Dies wird Ihnen wahrscheinlich dabei helfen, das Problem mit dem Update zu ermitteln.

Ich hoffe, das hilft allen anderen bei ähnlichen Problemen.

0
Kramerica317

Es gibt einen Konflikt, da Sie optimistisches Sperren verwenden. Beheben Sie Parallelitätsprobleme mit den ObjectStateManager-Einträgen und speichern Sie die Änderungen erneut. Einige Beispielcodes gibt es in MSDN site.

0
vijayst

In meinem Fall hatte ich einen zusammengesetzten Schlüssel und versuchte, einen Teil des Schlüssels zu aktualisieren (3 Spalten bilden einen zusammengesetzten Schlüssel, aus dem ich nur die 3. Spalte aktualisiert habe), aber EF erlaubte keine Änderung der Schlüsselwerte für dasselbe Objekt, I Aktualisierung des Datensatzes erreicht durch:

Context.Database.ExecuteSqlCommand(udpateCommand);
0
Sadiq

Nun, ich bin auch mit dieser Art von Parallelitätsfehler konfrontiert, als ich mit Entity Framework 6.13 mit Code First arbeitete. Ich habe auch stundenlang gekämpft, bevor ich es selbst gelöst habe. Es kann also jemandem da draußen helfen. Eine Tabelle wurde mit zusammengesetzten Primärschlüsseln erstellt. Heute habe ich die Struktur der Tabelle geändert und nur einen Primärschlüssel (mit AutoIncrement) anstelle von zusammengesetzten Schlüsseln erstellt und die Tabelle durch Migrationen mit fließenden API-Konfigurationen aktualisiert. Die Tabelle wurde aktualisiert, der Primärschlüssel wurde jedoch nicht mit AutoIncrement aktualisiert. Wenn ich versuchte, einen Datensatz hinzuzufügen, wurde der Parallelitätsfehler angezeigt. Als ich also die Autoincrement des Feldes festlegte, war der Fehler weg. Ich hoffe es hilft.

0
VID

Ich weiß nicht, was genau falsch war, aber ich habe diese Schritte einfach gemacht und es wurde gelöst. (Ich hoffe, dass Sie dieses Problem lösen können, da ich es konnte.)
Schritte sind wie folgt:
(1) Fügen Sie den neuen Controller mithilfe von Scaffolding basierend auf Ihrer edmx-Tabelle und dem DB-Kontext der EF-Datei ..__ hinzu.
(2) Wenn nun die Änderungen gespeichert werden, liegt das Problem in der Editiermethode .
(3) Jetzt kopieren Sie die Bearbeitungsmethode/den gesamten Controller aus dem Gerüst und fügen Sie ihn in Ihren ursprünglichen Controller ein.
(4) Erstellen Sie jetzt einfach das Programm und Voila.

Update
Ich habe herausgefunden, dass zur Bearbeitung von Daten aus der Ansicht alle Felder gesendet werden müssen, damit sie erneut an die Steuerung geschrieben werden. Wenn zum Zeitpunkt der Ausgabe eines der Felder aus der Entitätstabelle fehlt, kann es nicht bearbeitet werden. Insbesondere wenn sich PK in Label befindet und zur Bearbeitung an den Controller gesendet wird, wird dieser Fehler generiert. 

0

Dieser Fehler ist beim Erstellen eines Projekts aufgetreten. Es wurde sogar versucht, ein einfaches Einfügen auszuführen.

Wir haben das EF-Modell aus einer bereits vorhandenen Datenbank generiert, und das Framework setzte automatisch Entity Key = True in mehreren Feldern.

Wenn Sie alle außer der ID auf False setzen, wurde das Problem gelöst.

0
Wildcat Matt

Das ist mir beim Googeln aufgefallen. Ich hatte die gleiche Fehlermeldung, aber es stellte sich heraus, dass ich nicht einige obligatorische Nicht-Null-Werte festgelegt habe.

Vielleicht hilft dieser Fund jemandem.

0
r0m4n

Danke Terry, Fügen Sie Folgendes hinzu: Fügen Sie KEIN [Erforderlich] -Attribut zu Ihrem Schlüssel/Ihrer ID hinzu, wenn Sie ein Gerüst haben. Dies verhindert, dass Ihr Kontext den Schlüssel/die ID aus der URL zieht. Dies ist mir in einem Scaffold-Controller nach einer Migration passiert, die neue boolesche Felder im Modell enthielt. Diese Felder wurden nicht gesetzt.

0

Stellen Sie sicher, dass Sie die ID für beide Tabellen aus der Ansicht an das Modell übergeben. In Ihrem Fall ist dies der Schlüssel für die Tabelle Person und UserProfile . Wenn Sie die ID nicht auf der Seite anzeigen müssen, können Sie @ Html.HiddenFor (model => model.PersonId) und @ Html.HiddenFor hinzufügen (model => model.UserProfileId)

0