可跟踪实体主键违规 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,Action1 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, TaskCompletionSource1 完成,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, List1 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 问题的主要内容,如果未能解决你的问题,请参考以下文章

EF Core性能优化

EF Core:实体类型“用户”需要定义主键

EF并非我们想象的那么智能

Spring Data JPA主键违规约束不起作用

EF6 vs Entity Framework Core:插入实体而不将主键(身份)重置为零

EF ChangeTracker 访问被跟踪实体及其导航集合