EF编译查询偶尔会导致SqlException
Posted
技术标签:
【中文标题】EF编译查询偶尔会导致SqlException【英文标题】:EF Compiled Query occasionally causing SqlException 【发布时间】:2011-05-12 06:12:22 【问题描述】:我正在使用一个编译查询,它在应用程序中执行一部分查询逻辑非常复杂,它将编译查询抽象为 Func 后面。我会定期(大约一千次)收到以下异常:
SqlException:
The parameterized query '(@p__linq__0 int,@p__linq__1 nvarchar(4000),@p__linq__2 varchar(' expects the parameter '@p__linq__1', which was not supplied.
And InvalidOperationException:
Parameters cannot be added or removed from the parameter collection, and the parameter collection cannot be cleared after a query has been evaluated or its trace string has been retrieved.
看到第二个异常后,我的第一反应是遇到了并发问题。这是通过 WCF 服务在服务行为的默认配置下使用 basicHttpBinding 完成的,这意味着并发模式是单一的。我没有使用 InstanceContextMode 单一,而是使用默认的 PerSession,这可能会导致问题吗?
所涉及的数据库被大量使用,所以我也怀疑我可能在查询期间超时,但我无法与我看到的异常建立逻辑关联。
更糟糕的是,我无法在本地机器上重现这些错误,异常发生在晚上远程服务器上的处理例程中,而且每晚只有一两次。希望其他人也经历过类似的事情。我可以尝试一些事情,例如更改 instancecontextmode、增加 SQL Server 超时,但我更愿意在尝试解决方法之前知道问题出在哪里。我确实记录了一些异常实例,这是 InvalidOperationExceptions 之一的堆栈帧:
System.Data.Objects.ObjectParameterCollection.Add(ObjectParameter parameter)
System.Data.Objects.ELinq.CompiledELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
System.Linq.Enumerable.Count[TSource](IEnumerable`1 source, Func`2 predicate)
Processor.Processor.<>c__DisplayClass10.<GetObjectContexts>b__9(ObjectContextMetadata q) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\Processor\Processor.cs:line 174
System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext()
System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
Processor.Processor.<>c__DisplayClass10.<GetObjectContexts>b__c(ObjectContextMetadata q) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\Processor\Processor.cs:line 179
System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
Processor.Processor.ResolveGeoCode(AddressItem address, String product) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\Processor\Processor.cs:line 273
Company.ProcessingLogic.SomeService.SomeServiceService.ResolveDepotWithMask(AddressItem address, String product, DeliveryMap map, IGeocoder geocoder) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\SomeServiceService\SomeServiceService.cs:line 136
Company.ProcessingLogic.SomeService.SomeServiceService.ResolveDepotWithMask(AddressItem address, String product, DeliveryMap map) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\SomeServiceService\SomeServiceService.cs:line 59
Company.ProcessingLogic.SomeService.SomeServiceService.ResolveDepot(AddressItem address, String product) in C:\Documents and Settings\eugarps\My Documents\SomeService-development\SomeServiceService\SomeServiceService.cs:line 53
SyncInvokeResolveDepot(Object , Object[] , Object[] )
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
【问题讨论】:
【参考方案1】:这可能与您发送的数据有关。检查您是否发送为空。
编辑
这也可能是一种竞争条件。是否有可能 2 个线程同时使用同一个对象构建查询。如果是这样,您可能会遇到相同参数被添加两次的情况。
【讨论】:
谢谢,这看起来很有希望。下次我在办公室时,我会看看这是否有意义,但是相同的输入有时会导致错误,但有时不会导致错误,这就是我考虑并发的部分原因。 经过调查,我很确定这不是问题所在。然而,仍然没有解决。在我解决这个问题之前,我将实现一个存储过程而不是使用编译查询。以上是关于EF编译查询偶尔会导致SqlException的主要内容,如果未能解决你的问题,请参考以下文章