2017-10-11 49 views
1

在一位同事离开公司后,我继承了一些相当大的代码。不幸的是,他离开后的第二天,这个节目就被打破任何人都可以指出我在哪里看以下错误?附加一个“”类型的实体失败,因为另一个相同类型的实体已经具有相同的主键值

附加一个'MasT.DB.jobqueue'类型的实体失败,因为另一个相同类型的实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时可能会发生这种情况。这可能是因为一些实体是新的并且还没有收到数据库生成的关键值。在这种情况下,使用'Add'方法或'Added'实体状态来跟踪图形,然后根据情况将非新实体的状态设置为'Unchanged'或'Modified'。在

System.Data.Entity.Core.Objects.ObjectContext.VerifyRootForAdd(布尔doAttach,字符串entitySetName,IEntityWrapper wrappedEntity,EntityEntry existingEntry,EntitySet的&的EntitySet,布尔& isNoOperation)在System.Data.Entity.Core.Objects。 System.Data.Entity.Internal.Linq.InternalSet上的ObjectContext.AttachTo(String entitySetName,Object entity)1.<>c__DisplayClassa.<Attach>b__9() at System.Data.Entity.Internal.Linq.InternalSet System.Data.Entity.Internal.Linq中的1.ActOnSet(Action action,EntityState newState,Object entity,String methodName)。 InternalSet 1.Attach(Object entity) at System.Data.Entity.DbSet 1.在DT.ValidatorCore.JobQueue.MasTJobQueueMySql处附加(TEntity实体)。 <>在DT.ValidatorCore.JobQueue.MasTJobQueueMySql.MaintainJobQueue()处的DT.ValidatorCore.JobQueue.MasTJobQueueMySql.TakeJobsQueue(布尔includeCompleted)处的System.Collections.Generic.List上的c.b__23_7(jobqueue jq) ValidatorCore.JobQueue.MasTJobQueue.DoWork(字符串日期,布尔testRun,的Int32的runid)在DT.ValidatorCore.Commands.TriggerCommand.QueueCommand.Process(CmdTrigger 1 trigger) at DT.Common.Commands.BaseCommand 1.TriggerSubCommand(CmdTrigger 1 trigger) at DT.Common.Commands.Command 1.Process(CmdTrigger 1 trigger) at DT.Common.Commands.CommandMgr 1.Execute(CmdTrigger 1 trigger, BaseCommand 1 cmd,布尔silentFail)

我非常困惑,因为这不会发生在调试运行时,只有当程序在生产服务器上运行时,虽然他们连接到两个分离速率数据库,这些是相同的。

最初我只被要求更新代码的某些部分,所以这是一个很大的跳跃!

我相当肯定的问题是与DT.ValidatorCore.JobQueue.MasTJobQueueMySql.MaintainJobQueue,但我有实体框架

protected void MaintainJobQueue() 
    { 
     if (_jobQueueUnitOfWork != null) 
      _jobQueueUnitOfWork.Dispose(); 

     _jobQueueUnitOfWork = new JobQueueUnitOfWork(); 

     List<jobqueue> tempList = _jobQueueUnitOfWork.JobQueueRepository.GetAll(); 

     if (tempList == null) 
      return; 

     tempList.RemoveAll(jqItem => jqItem == null); 
     tempList.RemoveAll(jqItem => jqItem.packageinfo == null); 
     tempList.RemoveAll(jqItem => jqItem.packageinfo.pkg_content_id == null); 

     if (!tempList.Any()) 
      return; 

     var tempList2 = tempList.GroupBy(g => g.packageinfo.pkg_content_id + g.packageinfo.pkg_master_version + g.packageinfo.app_version).Select(x => x.ToList().OrderByDescending(m => m.packageinfo.app_revision).First()).ToList(); 

     tempList.RemoveAll(i => tempList2.Contains(i)); 
     tempList.ForEach(jq => context.jobqueue.Attach(jq)); 


     var pkgInfoRemovals = tempList.Select(i => i.packageinfo); 
     _jobQueueUnitOfWork.PackageInfoRepository.DeleteRange(pkgInfoRemovals); 

     var submissionpathRemovals = tempList.Select(i => i.submissionpath); 
     context.submissionpath.RemoveRange(submissionpathRemovals); 
     _jobQueueUnitOfWork.SubmissionPathRepository.DeleteRange(submissionpathRemovals); 


     _jobQueueUnitOfWork.JobQueueRepository.DeleteRange(tempList); 
    } 

    protected override void SaveChanges() 
    { 
     _jobQueueUnitOfWork.Save(); 
    } 

干杯的认识非常有限!

+0

很难通过只看到异常和代码来判断,但正如它所说的那样,您的表具有唯一的键约束,其中每个值必须是唯一的,并且您尝试使用重复键添加值。你能否确认所添加的行是新的还是修改的? – Equalsk

+0

这些行最初是在每天开始时添加的,然后在稍后更新。我创建了一个空白数据库,它将正确工作一天,然后在第二天早上出错 – OrangeFlavour

+0

因此......哪一位失败,添加或更新? – Equalsk

回答

0

由于您共享的代码似乎是围绕Entity Framework构建的包装,因此难以确定,因此掩盖了一些必要的细节,但有知识的人猜测您正在处理Detached Entities

要搜索的关键字是DbContext(数据库上下文)。

如果您使用实体框架(EF)从数据库中提取某些数据,则此数据将保留附加到数据库或DbContext,这是一个attached entity
EF现在会自动跟踪对数据所做的任何更改,因此当您拨打SaveChanges()时,它会知道现有数据为UPDATE

就你而言,我怀疑_jobQueueUnitOfWork.JobQueueRepository.GetAll();从其他地方(如Web API)获取数据。由于此数据是在DbContext以外创建的,因此EF不可能知道它处于什么状态,这是一个detached entity
解决方案是简单地告诉EF数据处于什么状态,在您的情况下它已被修改,并且需要UPDATE而不是INSERT

tempList.ForEach(jq => 
{ 
    context.jobqueue.Attach(jq); // Attach to `DbContext` 
    context.Entry(jq).State = System.Data.Entity.EntityState.Modified; // Modified 
}); 

如果您搜索与dbcontextchange trackingattached/detached entities实体框架的文章就应该多多回答你的问题。

+0

感谢您的回复,从星期五开始一直工作!我会深入地探讨Entity Framework的建议,这是我在未来几个月内需要了解的东西:) – OrangeFlavour

+0

没问题,很高兴它可以工作。通过点击左侧的绿色箭头接受工作通常是礼貌的;-) – Equalsk

+0

完成! :)需要一些声誉,然后我才可以公开投票! – OrangeFlavour

相关问题