2016-07-20 8 views
1

Ich habe ein Problem mit C# und Linq. Wenn ich einen Datensatz erstellen, in einem anderen Programm löschen (während das C# -Programm noch geöffnet ist) und den Datensatz in C# neu erstellen möchte, erhalte ich eine DuplicateKeyException, obwohl die Tabelle physisch leer ist. Eine Aktualisierung des Tisches hat nicht geholfen. Ich denke, es gibt einige Index-Cache betroffen.DuplicateKeyException nach dem Löschen von Datensatz in einem anderen Programm

Ich benutze MS SQL Server 2012

Schritt 1: etwas in die Tabelle einfügen.

CUSTOMERS test2 = new CUSTOMERS(); 
    test2.CUSTOMERID = 10; 
    test2.FOO = 1; 
    test2.BAR = 1; 
    CoreDB.CUSTOMERS.InsertOnSubmit(test2); 
    CoreDB.SubmitChanges(); 

Schritt 2: In einem anderen Programm (zum Beispiel SQL Explorer), den Datensatz entfernen.

Schritt 3: Aktualisieren Sie die Tabelle und überprüfen Sie die Anzahl der Datensätze.

CoreDB.Refresh(RefreshMode.OverwriteCurrentValues, CoreDB.CUSTOMERS); 
if (CoreDB.CUSTOMERS.Count(ds=> ds.CUSTOMERID == 10 && ds.FOO == 1 && ds.BAR == 1) == 0) { 
    MessageBox.Show("Good! Record not available anymore"); // <-- will be shown 
} 

Schritt 4: Versuchen Sie, den Datensatz wieder einzufügen. Es wird scheitern.

CUSTOMERS test1 = new CUSTOMERS(); 
    test1.CUSTOMERID = 10; 
    test1.FOO = 1; 
    test1.BAR = 1; 
    CoreDB.CUSTOMERS.InsertOnSubmit(test1); 
    CoreDB.SubmitChanges(); // <-- DuplicateKeyException 

Es funktioniert nur, wenn ich die Verbindung und öffnen Sie es erneut zu schließen. Wenn ich nur die Tabelle aktualisiere, wird die Zählung zu 0, aber es wird einen Indexkonflikt geben, obwohl die Tabelle physikalisch leer ist.

Was kann ich tun, damit es funktioniert, ohne die Verbindung immer zu öffnen/zu schließen?

Antwort

0

Haben Sie versucht, Ihre DbContext neu zu initialisieren, bevor Sie irgendwelche Aktualisierungen vornehmen?

Beginne mit Schritt 1

CoreDB = new YourContextHere(); //re-initialize context to clear memory changes 
CUSTOMERS test2 = new CUSTOMERS(); 
test2.CUSTOMERID = 10; 
test2.FOO = 1; 
test2.BAR = 1; 
CoreDB.CUSTOMERS.InsertOnSubmit(test2); 
CoreDB.SubmitChanges(); 

dann tun Schritt 2 und Schritt 3

Wie für Schritt 4, mit dem Schritt das gleiche tun 1

CoreDB = new YourContextHere(); //re-initialize context to clear memory changes 
CUSTOMERS test1 = new CUSTOMERS(); 
test1.CUSTOMERID = 10; 
test1.FOO = 1; 
test1.BAR = 1; 
CoreDB.CUSTOMERS.InsertOnSubmit(test1); 
CoreDB.SubmitChanges(); 

SubmitChanges Rollback Transaktionen/Operationen im Arbeitsspeicher nicht rückgängig gemacht und wird nicht von Ihrem aktuellen Db-Kontext (CoreDB) verfolgt, müssen Änderungen im Speicher manuell im Kontext zurückgesetzt werden, indem Sie es jedes Mal neu initialisieren Änderungen an Ihrer Datenbank vornehmen

+0

Vielen Dank für Ihre Antwort. Ich werde es versuchen. Aber ich verstehe die Sache mit den Transaktionen nicht. Übernimmt "SubmitChanges" die interne Transaktion nicht? (Daher gibt es keine "offene" Transaktion, die entweder zurückgesetzt oder festgeschrieben werden muss?) –

+0

Ja, "SubmitChanges" wird die interne Transaktion festschreiben, aber es werden NUR die im WITHIN ausgeführten TEMPLE committed, und nicht diejenigen außerhalb davon (wie Schritt 2). Da Ihr Kontext die Transaktion tatsächlich festgeschrieben hat, ist der Datenbankkontext, der in Ihrem Speicher "gespeichert" ist, derjenige ohne die Aktionen aus Schritt 2.Letztendlich müssen Sie Ihren Kontext aktualisieren, um die Änderungen zu erkennen, die außerhalb des besagten Kontexts durchgeführt werden. –

+0

Das heißt, es gibt keine "offene" Transaktion, wenn Sie "SubmitChanges" aufrufen, aber der Kontext wird für die spätere Wiederverwendung gespeichert (Derselbe genaue Kontext), es sei denn, Sie entscheiden sich für eine Neuinitialisierung –

Verwandte Themen