我有这段简单的代码:
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起作用,就像那些插入已被应用 D B。就像它没有听到错误。只有App restart才能使用实际数据刷新MyObjectContext。
如何在尝试执行INSERT后,从数据库返回有关错误的ObjectContext?
UPD:感谢您的回答。
当我尝试使用重复唯一键的AddObject时,我得到了这个:
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,它不应该存在,因为它没有进入数据库,因为插入时,数据库返回错误。 重复的人物对象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对象附加了对objectcontext的重复uniqueKey,它不应该存在。
答案 0 :(得分:1)
你怎么能说objectContext就像一切都很好?您执行另一个查询或只使用使用此新Person对象的导航属性?像
Person newPerson = someRelatedEntity.Persons.Where(p=>p.PersonID = "uniqueKey").FirstOrDefault();
当您调用AddObject时,您显然会将实体附加到上下文中,即使SaveChanges出错也会保留该实体,但是在此之后数据库可以检索此新对象时再次进行查询是不可能的。
但是如果您使用上面示例中的导航属性,则无需查询数据库,您可以看到新人如果存储了,无论如何您应该添加更多代码来更好地解释您的问题< / p>