2012-03-25 5 views
0

Ich habe dieses einfache Stück Code:EF Object Verhalten auf SQL INSERT Fehler

 MyObjectContext db = new MyObjectContext(); 

     Person new_person = new Person() { 
      /* some data, which does not satisfy 
      the constraints of unique key */ 
     }; 

     db.Person.AddObject(new_person); 
     db.SaveChanges(); 

In MSSQL-Datenbank-Tabelle ich einige eindeutigen Schlüssel in Tabelle Person haben. Wenn ich versuche, new_person Objekt hinzufügen, die aufgrund eindeutiger Einschränkungen nicht hinzugefügt werden können, gibt Datenbank einen Fehler zurück, wie erwartet, aber in weiteren Arbeit MyObjectContext handelt, wie diese Insertionen wurde von DB angewendet. Als hätte es keinen Fehler gehört. Nur App-Neustart hilft MyObjectContext mit den tatsächlichen Daten zu aktualisieren.

Wie erhalten ObjectContext benachrichtigt über den Fehler, von der Datenbank zurückgegeben, nach dem Versuch, INSERT durchzuführen?




UPD: Vielen Dank für Ihre Antworten.

Wenn ich versuche, mit doppelten eindeutigen Schlüsseln zu addObject, bekomme ich diese:

Server Error in '/' Application. 
Violation of UNIQUE KEY constraint 'IX_Person'. Cannot insert duplicate key in object 'dbo.Person'. 
The statement has been terminated. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'IX_Person'. Cannot insert duplicate key in object 'dbo.Person'. 
The statement has been terminated. 

Source Error: 

Line 34: 
Line 35:   db.Person.AddObject(new_person); 
>Line 36:   db.SaveChanges(); 
Line 37: 
Line 38:   return Json(new ViewPerson(new_person)); 


Source File: C:\DEV\MyProject\Controllers\PersonController.cs Line: 36 

Stack Trace: 

[SqlException (0x80131904): Violation of UNIQUE KEY constraint 'IX_Person'. Cannot insert duplicate key in object 'dbo.Person'. 
The statement has been terminated.] 
    System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2073550 
    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5064508 
    System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234 
    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275 
    System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33 
    System.Data.SqlClient.SqlDataReader.get_MetaData() +86 
    System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +311 
    System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32 
    System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141 
    System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12 
    System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10 
    System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) +8167912 
    System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +267 



Danach in nächsten Anforderung zum Server ich die Ausnahme in der zweiten Zeile dieses Codes erhalten:

Category some_category = MyEntitiesHelper.db.Category.Single(c => c.ID == 1); 
Person some_person = some_category.Person.SingleOrDefault(p => p.UniqueID == "uniqueKey"); 

System.InvalidOperationException: {“ Sequenz enthält mehr als ein Anpassungselement "}

Diese happenned, weil (ich während Debug-Sitzung überprüft), in some_category.Person es war eine andere Person mit doppelten UniqueKey, die nicht da sein sollte, weil es ging nicht zur Datenbank, weil die Datenbank beim Einfügen einen Fehler zurückgegeben hat. Doppelte Person Objekt hatte ID = 0.



By the way, Object Objekt wie folgt erstellt:

public static class MyEntitiesHelper 
{ 

    private static MyObjectContext _db; 
    public static MyObjectContext db 
    { 
     get 
     { 
      if (_db == null) _db = new MyObjectContext(); 
      return _db; 
     } 
    } 


} 

neue Instanz wird für jede Anforderung erstellt wird, oder es isn` t? Ist das ein guter Ansatz?



Die Frage bleibt das gleiche: wie „Sequenz enthält mehr als ein Anpassungselement“ Ausnahme zu verhindern, während

Person some_person = some_category.Person.SingleOrDefault(p => p.UniqueID == "uniqueKey"); 

versuchen Es Sekunde Person-Objekt mit doppelten UniqueKey angebracht zu objectcontext, der nicht dort sein sollte.

+0

Welchen Umfang hat der Kontext? Ist es Anwendung oder Anfrage? – Eranga

+0

Können Sie bitte die genaue Ausnahmebedingungsnachricht und die Stapelverfolgung posten? –

+0

Es tut mir leid, aber Ihre Frage ist unklar. Ich verstehe nicht, wonach du wirklich verlangst. Die Frage, die Sie gestellt haben: "Wie wird der Objektkontext auf den Fehler angezeigt, der von der Datenbank zurückgegeben wurde, während versucht wurde, INSERT auszuführen?" macht keinen logischen Sinn, bitte verfeinern Sie Ihre Frage in etwas Verständliches. –

Antwort

1

Wie können Sie sagen, dass objectContext funktioniert wie alles in Ordnung? Sie führen eine andere Abfrage aus oder verwenden nur eine Navigationseigenschaft, die dieses neue Person-Objekt verwendet?wie

Person newPerson = someRelatedEntity.Persons.Where(p=>p.PersonID = "uniqueKey").FirstOrDefault(); 

Wenn Sie AddObject rufen Sie offensichtlich das Unternehmen auf den Kontext anhängen und es bleibt, auch wenn Savechanges schief geht, aber es kann nicht möglich sein, dass eine andere Zeit, um die Datenbank abfragen nach, dass dieses neue Objekt abrufen.

Wenn Sie jedoch eine Navigationseigenschaft wie im obigen Beispiel verwenden, müssen Sie die Datenbank nicht abfragen, und Sie können die neue Person sehen, wenn sie gespeichert wird. Sie sollten jedoch mehr Code eingeben, um das Problem besser zu erklären

+0

Ja, ich verwende Navigationseigenschaften, wie Sie gesagt haben. Gibt es eine Möglichkeit, Änderungen im Kontext rückgängig zu machen, wenn SaveChanges schief geht? – Roman

+0

Leider nicht, wenn Sie ad hoc nur die Einfügung einer Entität verwalten möchten, könnten Sie die Ausnahme fangen und die Entität manuell trennen, wenn das Speichern nicht gut ging, sonst könnten Sie einfach einen neuen Objektkontext nach dem Speichern deklarieren und er hat gewonnen Sie haben keine angehängten Entitäten, praktisch jede Änderung rückgängig machen, die Sie vorgenommen haben, wird es erneut die Datenbank abfragen, die die wirklichen gespeicherten Daten erhält – MaRuf