У меня есть этот простой кусок кода:
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();
В таблице базы данных MSSQL у меня есть уникальный ключ в таблице Person.
Когда я пытаюсь добавить объект new_person
, который не может быть добавлен из-за уникальных ограничений, база данных возвращает ошибку, как и ожидалось, но в дальнейшей работе MyObjectContext действует, подобно этим вставкам было применено БД. Как будто не слышал ошибки. Только перезапуск приложения помогает обновить MyObjectContext актуальными данными.
Как получить ObjectContext, уведомленный об ошибке, возвращенной из базы данных, после попытки выполнить INSERT?
UPD: Спасибо за ваши ответы.
Когда я пытаюсь добавить объект с двойным уникальным ключом, я получаю это:
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
После этого в следующем запросе к серверу я получаю исключение во второй строке этого кода:
Category some_category = MyEntitiesHelper.db.Category.Single(c => c.ID == 1);
Person some_person = some_category.Person.SingleOrDefault(p => p.UniqueID == "uniqueKey");
System.InvalidOperationException: {"Последовательность содержит более одного совпадающего элемента"}
Это произошло, потому что (я проверял во время сеанса отладки), в some_category.Person было был другой человек с дубликатом uniqueKey, которого не должно быть, потому что он не пошел в базу данных, потому что при вставке база данных вернула ошибку.
Дублированный объект person имел ID = 0.
Кстати, объект ObjectContext создается так:
public static class MyEntitiesHelper
{
private static MyObjectContext _db;
public static MyObjectContext db
{
get
{
if (_db == null) _db = new MyObjectContext();
return _db;
}
}
}
Новый экземпляр создается для каждого запроса, или это не так? Это хороший подход?
Вопрос остается тем же: как предотвратить исключение «Последовательность содержит более одного совпадающего элемента» при попытке
Person some_person = some_category.Person.SingleOrDefault(p => p.UniqueID == "uniqueKey");
Существует второй объект Person с дубликатом uniqueKey, прикрепленным к objectcontext, которого там быть не должно.