1

Ich benutze Mssql als db und EF4 als ORM/DAL.
Meine Frage bezieht sich auf den folgenden Code:Sollte ich vor dem Löschen prüfen, ob eine Zeile existiert?

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 
    Entities.PlayerBuildings.Attach(playerBuilding); 
    Entities.PlayerBuildings.DeleteObject(playerBuilding); 
    Entities.SaveChanges(); 
} 

Wenn die Zeile dieses sehr gut existiert funktioniert, wenn nicht ich eine Ausnahme erhalten (Shop aktualisieren, einfügen oder Anweisung löschen eine unerwartete Anzahl der betroffenen Zeilen . (0) Entities modifiziert worden sein oder gestrichen, da Einheiten geladen wurden aktualisieren Object Einträge)
Soll ich eine Rundreise an der Datenbank vornehmen zu überprüfen, ob die Zeile wie folgt vorhanden:..

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = (from p in Entities.PlayerBuildings 
            where p.BuildingID == buildingId && p.CountryID == countryId 
            select p).FirstOrDefault(); 
    if (playerBuilding != null) 
    { 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

Ich denke, dass extra Rundreise irgendwie unnötig ist, denn ohne die EF, mit einfachen SQL konnte ich einfach die Zeile mit einem einzigen DELETE-Befehl löschen.

Was wäre eine bessere Praxis?

Antwort

0

Dieser Fehler ist ein Nebeneffekt der optimistischen Parallelität von Entity Framework.

Im Grunde könnte jemand anderes den Datensatz zwischen dem Abrufen gelöscht haben. Oder vielleicht hast du etwas mit der Entität vor diesem Code getan.

Versuchen Sie es in einer isolierten Umgebung auszuführen (z. B. einen Komponententest), um zu sehen, ob das Problem weiterhin auftritt.

Ja, Sie es sicher und erhalten den Datensatz wieder spielen konnte, oder man könnte ObjectContext.Refresh verwenden:

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 

    try 
    { 
     Entities.PlayerBuildings.Attach(playerBuilding); 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
    catch (OptimisticConcurrencyException) 
    { 
     Entities.Refresh(RefreshMode.ClientWins, playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

Auf einer seitlichen Anmerkung - vielleicht ist es, weil Ihre Methode statische ist? Wie instanzist du deinen Kontext? Ich hoffe, du verwendest kein Singleton. :(

Es gibt einen ausgezeichneten Artikel über EF Parallelität here, die weiter im Detail erklärt, warum Sie diesen Fehler bekommen, und was kann Schritte getan werden, um das entgegenzuwirken.

+0

danke für den Kommentar RPM, aber Dies ist kein optimistisches Nebenläufigkeitsproblem.Ich arbeite an einem lokalen Entwicklercomputer, versuchte nicht statische Methode, das nicht das Problem auch nicht.Der Kontext wird instanziiert mit dieser Methode: http://dotnetslackers.com/articles/ado_net/Managing -Entity-Framework-ObjectContext-Lebensdauer-und-Scope-in-N-Layered-ASP-NET-Anwendungen.aspx.Verwenden Sie die normale Möglichkeit, den Kontext instanziieren, nichts zu ändern. – Adir

+0

Werfen Sie einen Blick auf den Artikel - der Fehler in das ist arti Derselbe ist genau der gleiche wie dein. Haben Sie versucht, den obigen Code in einem Komponententest auszuführen (isoliert)? Auch - wie in diesem Artikel haben Sie den Kontext instanziiert? (Es gibt mehrere Methoden in diesem Artikel) – RPM1984

+0

Ich habe die UnitOfWorkScope-Methode verwendet, aber das ist nicht das Problem. Selbst wenn ich den Kontext auf die alte Art instanziiere (MyContext context = new MyContext()), wird derselbe Fehler weiterhin angezeigt. Ich glaube nicht, dass es mit Parallelität zusammenhängt, der Fehler wird angezeigt, weil ich versuche, ein Objekt zu löschen, das im Kontext nicht existiert. – Adir