可跟踪实体主键违规 EF 4 问题
Posted
技术标签:
【中文标题】可跟踪实体主键违规 EF 4 问题【英文标题】:Trackable entities Primary key violation EF 4 Issue 【发布时间】:2015-05-08 13:49:14 【问题描述】:我的情况很奇怪。我们有一个使用 EF 4 跟踪实体的 .NET 4.5 应用程序。在我们的 DEV/QA/UAT 环境中一切正常。但是 EF 因主键违规而在生产中失败。我们有一个 Table 和一个与 Parent Table 有一个外键的 Table,而这个外键也是 Child 表中的主键。
执行更新的代码获取的实体中也包含引用的实体。我们开始跟踪业务层中的 和 ,然后进行一些更新,然后传递到数据访问层进行实际更新。数据访问层代码如下:
internal static TEntity EntitySave<TEntity>(this TEntity entity, bool
enableTracking = true) where TEntity : class, IObjectWithChangeTracker
if (entity == null)
return entity;
MasterEntities context = null;
try
context = new MasterEntities();
if (!entity.ChangeTracker.ChangeTrackingEnabled) // This code isn't really doing anything since turning on tracking at this point doesn't matter
// ""
entity.StartTracking(); // ""
// ""
context.EntityRoot<TEntity>().ApplyChanges(entity);
context.SaveChanges();
if (enableTracking)
context.ResetAllTracking();
catch (Exception ex)
new GroupM.ToolLib.AppException.Ex(false, ex, "Error in RepositoryHelpers; Method: EntitySave",
GroupM.ToolLib.AppException.ExType.Error,
GroupM.ToolLib.AppException.ExDestination.AppDefaultLogFile);
finally
if (context != null)
context.Dispose();
return entity;
堆栈跟踪是:
Exception=更新条目时出错。见内 细节例外。方法=更新源=System.Data.Entity 堆栈跟踪 = 在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter 适配器)在 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions 选项) 在 DataMarketplace.DataAccess.Repositories.RepositoryHelpers.EntitySave[TEntity](TEntity 实体,布尔启用跟踪) InnerException=System.Data.SqlClient.SqlException (0x80131904): 违反 PRIMARY KEY 约束“PK_DataFeedQueries”。不能 在对象“dbo.DataFeedQueryState”中插入重复键。复制品 键值为(3383)。该语句已终止。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, Boolean breakConnection,Action
1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource
1 完成,Int32 超时,Task& 任务, 布尔 asyncWrite) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法)在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)在 System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator 翻译器,EntityConnection 连接,Dictionary2 identifierValues, List
1 generatedValues)在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter 适配器) ClientConnectionId:9abb68fe-3424-45d8-a174-88ed692ac5fd 自定义 消息文本=RepositoryHelpers 中的错误;方法:EntitySave 机器 名称=WEB02-PROD
我已完成以下故障排除:
-
从我的本地机器调试问题并指向生产数据库,它工作正常。所以它让我相信代码可能不一样。
-
我将代码从我们的 UAT 环境复制到了生产网络服务器。但我仍然得到同样的错误。这让我相信数据库架构或其他一些设置可能不一样。
UAT 和 Prod 之间的比较数据库架构。它们是相同的。
关于如何进一步解决此问题的任何想法。试了几天。
提前感谢您的任何建议。
【问题讨论】:
【参考方案1】:我猜你是手动管理主键而不是数据库。
如果是这种情况,您可能会为具有相同 id 的同一个表获得两个并发插入,这违反了主键约束。
【讨论】:
数据库中没有主键,EF 模型基于数据库架构。 是的。主键在数据库中。但是这些主键的值是如何产生的呢?通过代码还是通过数据库自动? 由数据库自动生成。这是一个身份列 你能告诉我生产数据库中以下查询的输出吗?DBCC CHECKIDENT ('DataFeedQueryState', NORESEED);
以上是关于可跟踪实体主键违规 EF 4 问题的主要内容,如果未能解决你的问题,请参考以下文章