Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 Can';t查询TPL下的EF上下文_C# 4.0_Entity Framework 4_Task Parallel Library - Fatal编程技术网

C# 4.0 Can';t查询TPL下的EF上下文

C# 4.0 Can';t查询TPL下的EF上下文,c#-4.0,entity-framework-4,task-parallel-library,C# 4.0,Entity Framework 4,Task Parallel Library,我有一个从数据库中读取数千条记录的过程,将每条记录编码成一条单独的XML消息,然后将所述消息发送到WCF服务 数据库通过EF4模型引用。我正在使用TPL来并行创建XML消息。问题发生在第一个LINQ查询中: var practice = (from patient in db.T_AccountHolder join practitioner in db.T_Practitioner on patient.DefaultPractitioner_ID equals

我有一个从数据库中读取数千条记录的过程,将每条记录编码成一条单独的XML消息,然后将所述消息发送到WCF服务

数据库通过EF4模型引用。我正在使用TPL来并行创建XML消息。问题发生在第一个LINQ查询中:

var practice = (from patient in db.T_AccountHolder
                join practitioner in db.T_Practitioner on patient.DefaultPractitioner_ID equals practitioner.Practitioner_ID
                join _practice in db.T_Practice on practitioner.Practice_ID equals _practice.Practice_ID
                where patient.AccountHolder_ID == accountholder_id
                select _practice).FirstOrDefault();
我得到以下例外情况:

ArgumentException: An item with the same key has already been added.
经过大量研究,我发现EF不会为类似的查询结果分配新的键,这意味着如果使用相同的结果查询相同的表,则会出现上述异常(因为结果位于相同的datacontext中)

因为我在使用第三方物流,我正处于这种情况。是我唯一不使用EF的方法吗?返回正常的ADO.NET查询

我上下搜索了这个优秀的网站和谷歌,但似乎找不到类似的问题


编辑:这是错误的堆栈跟踪

Exception message: An item with the same key has already been added.

at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Objects.ObjectStateManager.AddStateManagerTypeMetadata(EntitySet entitySet, ObjectTypeMapping mapping)
at System.Data.Objects.ObjectStateManager.GetOrAddStateManagerTypeMetadata(Type entityType, EntitySet entitySet)
at System.Data.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at WCFServiceTest.Messages.CreateAccountHolderMessage(Int32 accountholder_id) in C:\Users\Chris\documents\visual studio 2010\Projects\WCFServiceTest\WCFServiceTest\Messages.cs:line 116
at WCFServiceTest.Messages.CreateParallelMessagesForAccountHolder(Int32 accountholder_id, manmayEntities _db, List`1 queue) in C:\Users\Chris\documents\visual studio 2010\Projects\WCFServiceTest\WCFServiceTest\Messages.cs:line 2482
at WCFServiceTest.ParallelWork.<>c__DisplayClass22.<ProcessData_EF>b__1f(Int32 patient_id) in C:\Users\Chris\documents\visual studio 2010\Projects\WCFServiceTest\WCFServiceTest\ParallelWork.cs:line 298
异常消息:已添加具有相同密钥的项。
在System.ThrowHelper.ThrowArgumentException(异常资源)
at System.Collections.Generic.Dictionary`2.Insert(TKey键、TValue值、布尔加法)
位于System.Data.Objects.ObjectStateManager.AddStateManagerTypeMetadata(EntitySet EntitySet,ObjectTypeMapping)
位于System.Data.Objects.ObjectStateManager.GetOradStateManagerTypeMetadata(类型entityType,EntitySet EntitySet)
在System.Data.Objects.ObjectStateManager.AddEntry(EntityRapper wrappedObject、EntityKey passedKey、EntitySet EntitySet、String argumentName、Boolean isAdded)
位于System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 ConstructionEntityDelegate,EntityKey EntityKey,EntitySet EntitySet)
lambda_法(闭合、整形器)
在System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(整形器整形器整形器)
位于System.Data.Common.Internal.Materialization.Shaper`1.SimpleNumerator.MoveNext()
位于System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1源)
在System.Data.Objects.Elink.ObjectQueryProvider.b__1[TResult](IEnumerable`1序列)
在System.Data.Objects.Elink.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1查询,表达式queryRoot)
位于System.Data.Objects.Elink.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](表达式)
位于System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1源)
在C:\Users\Chris\documents\visualstudio 2010\Projects\WCFServiceTest\WCFServiceTest\Messages.cs中的WCFServiceTest.Messages.CreateAccountHolderMessage(Int32 accountholder_id)中:第116行
在C:\Users\Chris\documents\visualstudio 2010\Projects\WCFServiceTest\WCFServiceTest\Messages.cs中的WCFServiceTest.Messages.CreateParallelMessagesForAccountHolder(Int32 accountholder\u id,manmayEntities\u db,列表'1队列)中
在WCFServiceTest.ParallelWork.c__中,以c:\Users\Chris\documents\visualstudio 2010\Projects\WCFServiceTest\WCFServiceTest\ParallelWork.cs:第298行显示Class22.b__1f(Int32患者id)
经过大量研究,我发现EF不会为类似的查询结果分配新的键,这意味着如果使用相同的结果查询相同的表,则会出现上述异常(因为结果位于相同的datacontext中)

那是不对的。可以多次运行相同的查询。在测试应用程序中尝试它

如果在上下文中选择同一对象两次,默认情况下,实例将固定为同一对象。有关
ObjectQuery.MergeOption
,请参阅文档

当您对同一对象执行两次
AddObject()
操作时,通常会看到您给出的错误

我想你的虫子可能在别处

顺便说一句,我会这样写你的查询:

var practice = (from patient in db.T_AccountHolder
                where patient.AccountHolder_ID == accountholder_id
                select patient.Practitioner.Practice).FirstOrDefault();

不过,这个问题不应该有任何区别。

我也有同样的问题,在阅读carig Response之后,我的想法是我可以使用一些锁来处理它

它以某种方式工作,我不知道有多少,但上一次我在多线程应用程序第3或第4次后出现错误,同步进入该部分,但这次,它没有大约10次(测试调试)(顺便说一句,我没有再次面对该错误)

我有2个线程同步检查数据库中的可用作业。。。然后他们同时寻找工作,由于数据库在响应之前的延迟,所以我认为它完成了工作

正如您所看到的,线程正在锁中等待,因此EF每次只处理一个相同的查询,并且它停止了错误


更好的方法是,这些线程到达缓存列表,几秒钟后,您让线程触发另一个线程,该线程将用新数据填充缓存,这样您总是有最新的数据,并且您不会让数据库承受获取相同数据的压力,所以锁可以消失。。。(如果您不需要确切的最新数据)

为每个线程指定一个新的上下文不是答案。今天早上尝试了,得到了类似的结果(“实体已经存在”类型的错误)。感谢您的回复。然而,这是我正在使用的一个测试应用程序,多个线程(通过TPL框架)确实会导致所述异常。按顺序运行相同的代码不会产生错误。我理解这一点,但我仍然不认为这一行是导致错误的原因。您是否查看了与异常关联的堆栈跟踪?可以发布吗?已添加请求的堆栈跟踪。需要为每个线程指定新上下文(如您所说),但这还不够。您根本不能在线程之间共享(附加)实体,因为这会隐式地引入其他上下文。堆栈跟踪显示ObjectStateManager似乎由多个线程共享,因此这里可能就是这样。谢谢,Craig。我不确定如何使这些EF调用更明确以避免此错误。此后,我将EF调用重新编写为普通ADO.net调用,并从使用TPL中获得了预期的结果和好处。