2013-08-28 8 views
5

Im Entity-Framework, mit gespeicherten Prozeduren, möchte ich eine Aktualisierung auf meiner Tabelle mit optimistischer Parallelität durchführen. Ich konnte das nicht funktionieren, ohne meine vorhandene gespeicherte Update-Prozedur zu ändern. Ich versuche festzustellen, ob es eine Möglichkeit gibt, meine vorhandene gespeicherte Prozedur zuzuordnen, so dass eine Gleichzeitigkeitsausnahme auftreten wird, wenn keine Zeilen aktualisiert werden.Optimistische Parallelität mit Stored Procedures in Entity Framework

Einige Hintergrundinformationen:

  • ich das Update gespeicherte Prozedur (einschließlich der Zeitstempel) Spalte in meiner .edmx Datei
  • Meine bestehende gespeicherte Prozedur sieht wie folgt aus (die tatsächlichen Tabellennamen zugeordnet haben und Spalten sind offensichtlich weggelassen):

    UPDATE Table SET Column = @Column1, Column2 = @Column2 .... 
    WHERE PK = @PK AND Timestamp = @Timestamp 
    
    SELECT PK, Column1, Column2, ....., Timestamp 
    FROM Table WHERE PK = @PK 
    
  • für den Fall, dass das Update (aufgrund einer Zeitmarke Mismatch nicht), um den ausgewählten Teil der gespeicherten Prozedur wird noch eine Zeile zurückgeben.

Wenn ich die gespeicherte Prozedur der folgenden ändern:

UPDATE Table SET Column = @Column1, Column2 = @Column2 .... 
    WHERE PK = @PK AND Timestamp = @Timestamp 

    IF @@ROWCOUNT > 0 
     SELECT PK, Column1, Column2, ....., Timestamp 
     FROM Table WHERE PK = @PK 

Dann funktioniert alles wie erwartet, und die Gleichzeitigkeit Fehler auftritt.

Wenn die gespeicherte Prozedur einen Ausgabeparameter zurückgibt und diesen Ausgabeparameter dem "Rows Affected Parameter" in der .edmx-Datei des Entity Framework zuordnet, funktioniert der Parallelitätsfehler ebenfalls wie erwartet.

Diese Lösung (dh die Ausgangsparameter verwendet) wird am besten erklärt, fand ich, hier: http://petermannerhult.wordpress.com/2010/10/01/entity-framework-4-with-optimistic-concurrency-and-stored-procedures/

Keines der oben genannten Schritte scheint, wie sie allerdings notwendig sein sollten, wie ich, dass das Entity Framework übernehmen würde könnte Verwenden Sie einfach die Anzahl der aktualisierten Zeilen, um festzustellen, ob eine Nebenläufigkeitsausnahme auftreten sollte. Ich habe diese genau gespeicherten Prozeduren (mit optimistischer Parallelität) in ADO.NET DataSets ohne jedes Problem verwendet. Meine Frage ist also, wie kann ich meine vorhandenen gespeicherten Prozeduren ohne Änderung verwenden, um optimistische Parallelität im Entity Framework zu ermöglichen?

+2

Ich glaube nicht, dass es ein Problem mit EF ist. EF hat keinen Zugriff auf die Zeilenanzahl Ihrer Update-Anweisungen in Ihrem gespeicherten Prozess. Sie müssen also diese Überprüfung selbst durchführen, indem Sie rowcount in Ihrem proc überprüfen oder indem Sie den rowcount aus dem proc zurückgeben, damit EF herausfinden kann, ob die Zeile aktualisiert wurde. – Satish

+0

@Satish Danke für die Antwort, aber könnten Sie mir erklären, warum die EF keinen Zugriff auf die Zeilenanzahl meiner Update-Anweisung hat? Diese Information sollte verfügbar sein, wenn eine gespeicherte Prozedur in SQL Server ausgeführt wird. Zum Beispiel kann mit der RecordsAffected-Eigenschaft eines SqlDataReaders darauf zugegriffen werden (siehe http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.recordsaffected.aspx). Angesichts der Tatsache, dass diese genau gespeicherte Prozedur in ADO.NET (mit optimistischer Parallelität) funktioniert, muss es möglich sein, die Anzahl der aktualisierten Zeilen zu bestimmen. Gibt es einen Grund, warum die EF das nicht kann? – actf

+0

Wenn Sie eine gespeicherte Prozedur haben, kennt der Aufrufer der Prozedur die Zeilenzähler der einzelnen Anweisungen in Ihrer Prozedur nicht. Wenn Sie den gleichen Proc mit ADO.NET aufrufen würden, würde ich denken, dass er sich genauso verhält wie EF. – Satish

Antwort

0

Die SELECT sollte auch die gleiche WHERE-Klausel wie UPDATE haben.

UPDATE Table SET Column = @Column1, Column2 = @Column2 .... 
WHERE PK = @PK AND Timestamp = @Timestamp 

SELECT PK, Column1, Column2, ....., Timestamp 
WHERE PK = @PK AND Timestamp = @Timestamp 
0

Wenn Sie wirklich, können Sie die Zeitstempel von der gespeicherten Prozedur zurück vergleichen Sie nicht wollen, um den Code der gespeicherten Prozedur ändern, um die Zeitstempel hinein geführt. Wenn es anders ist, haben Sie einen Parallelitätsfehler.

Verwandte Themen