已经有一个打开的DataReader与这个Command关联,必须先closures它
我有这个查询,我得到这个函数的错误:
var accounts = from account in context.Accounts from guranteer in account.Gurantors select new AccountsReport { CreditRegistryId = account.CreditRegistryId, AccountNumber = account.AccountNo, DateOpened = account.DateOpened, }; return accounts.AsEnumerable() .Select((account, index) => new AccountsReport() { RecordNumber = FormattedRowNumber(account, index + 1), CreditRegistryId = account.CreditRegistryId, DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber), AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber) }) .OrderBy(c=>c.FormattedRecordNumber) .ThenByDescending(c => c.StateChangeDate); public DateTime DateLastUpdated(long creditorRegistryId, string accountNo) { return (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); }
错误是:
已经有一个打开的DataReader与这个Command关联,必须先closures它。
更新:
堆栈跟踪添加:
InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.] System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5008639 System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +23 System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +144 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +87 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12 System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10 System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +443 [EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.] System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +479 System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute(ObjectContext context, ObjectParameterCollection parameterValues) +683 System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +119 System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +38 System.Linq.Enumerable.Single(IEnumerable`1 source) +114 System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3(IEnumerable`1 sequence) +4 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +29 System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +91 System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +69 System.Linq.Queryable.Max(IQueryable`1 source) +216 CreditRegistry.Repositories.CreditRegistryRepository.DateLastUpdated(Int64 creditorRegistryId, String accountNo) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1497 CreditRegistry.Repositories.CreditRegistryRepository.<AccountDetails>b__88(AccountsReport account, Int32 index) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1250 System.Linq.<SelectIterator>d__7`2.MoveNext() +198 System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217 System.Linq.<GetEnumerator>d__0.MoveNext() +96
如果在迭代另一个查询的结果时执行查询,则可能发生这种情况。 从您的示例中不清楚发生这种情况的原因是该示例不完整。
有一件事情可能会导致这种情况是在遍历某些查询的结果时触发的延迟加载。
通过在连接string中允许MARS可以很容易地解决这个问题。 将MultipleActiveResultSets=true
添加到连接string的提供者部分(其中指定了数据源,初始目录等)。
您可以在return
语句之前使用ToList()
方法。
var accounts = from account in context.Accounts from guranteer in account.Gurantors select new AccountsReport { CreditRegistryId = account.CreditRegistryId, AccountNumber = account.AccountNo, DateOpened = account.DateOpened, }; return accounts.AsEnumerable() .Select((account, index) => new AccountsReport() { RecordNumber = FormattedRowNumber(account, index + 1), CreditRegistryId = account.CreditRegistryId, DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber), AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)}).OrderBy(c=>c.FormattedRecordNumber).ThenByDescending(c => c.StateChangeDate).ToList(); public DateTime DateLastUpdated(long creditorRegistryId, string accountNo) { var dateReported = (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); return dateReported; }
在我的情况下,使用Include()
解决了这个错误,根据情况可以更有效地发出多个查询时,它可以一起查询一次连接。
IEnumerable<User> users = db.Users.Include("Projects.Tasks.Messages"); foreach (User user in users) { Console.WriteLine(user.Name); foreach (Project project in user.Projects) { Console.WriteLine("\t"+project.Name); foreach (Task task in project.Tasks) { Console.WriteLine("\t\t" + task.Subject); foreach (Message message in task.Messages) { Console.WriteLine("\t\t\t" + message.Text); } } } }
这是一个需要参考的人的工作连接string。
<connectionStrings> <add name="IdentityConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\IdentityDb.mdf;Integrated Security=True;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" /> </connectionStrings>
我不知道这是否重复的答案。 如果是我很抱歉。 我只想让有需要的人知道如何使用ToList()解决我的问题。
在我的情况下,我有同样的exception下面的查询。
int id = adjustmentContext.InformationRequestOrderLinks.Where(item => item.OrderNumber == irOrderLinkVO.OrderNumber && item.InformationRequestId == irOrderLinkVO.InformationRequestId).Max(item => item.Id);
我解决了如下
List<Entities.InformationRequestOrderLink> links = adjustmentContext.InformationRequestOrderLinks .Where(item => item.OrderNumber == irOrderLinkVO.OrderNumber && item.InformationRequestId == irOrderLinkVO.InformationRequestId).ToList(); int id = 0; if (links.Any()) { id = links.Max(x => x.Id); } if (id == 0) { //do something here }
使用语法.ToList()
将从数据库中读取的对象转换为列表,以避免再次重读。希望能为它工作。 谢谢。
看起来你使用相同的EF上下文从一个活动查询中调用DateLastUpdated,而DateLastUpdate向数据存储本身发出一个命令。 entity framework一次只支持每个上下文的一个活动命令。
你可以重构你的上面两个查询到这样一个:
return accounts.AsEnumerable() .Select((account, index) => new AccountsReport() { RecordNumber = FormattedRowNumber(account, index + 1), CreditRegistryId = account.CreditRegistryId, DateLastUpdated = ( from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(), AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber) }) .OrderBy(c=>c.FormattedRecordNumber) .ThenByDescending(c => c.StateChangeDate);
我也注意到你在查询中调用FormattedAccountNumber和FormattedRecordNumber等函数。 除非这些存储过程或函数是从数据库导入到实体数据模型中的,并且映射正确,否则它们将抛出except,因为EF不知道如何将这些函数转换为可以发送到数据存储的语句。
另外请注意,调用AsEnumerable不会强制查询执行。 直到查询执行被推迟到枚举。 如果你愿意,你可以用ToList或ToArray强制枚举。
除了Ladislav Mrnka的回答:
如果要在“设置”选项卡上发布和重写容器,则可以将“ MultipleActiveResultSet”设置为“True”。 您可以通过单击高级…find此选项,它将在高级组。
我有同样的错误,当我试图更新读循环内的一些logging。 我已经尝试了最多投票答案MultipleActiveResultSets=true
,发现,这只是解决方法,以获得下一个错误
新的事务是不允许的,因为会话中还有其他线程正在运行
对于大型的ResultSets来说,最好的方法是使用块并为每个块打开单独的上下文,如entity framework中的SqlException所述- 不允许新的事务,因为会话中还有其他线程正在运行
我通过改变await _accountSessionDataModel.SaveChangesAsync()来解决这个问题。 to _accountSessionDataModel.SaveChanges(); 在我的Repository类中。
public async Task<Session> CreateSession() { var session = new Session(); _accountSessionDataModel.Sessions.Add(session); await _accountSessionDataModel.SaveChangesAsync(); }
将其更改为:
public Session CreateSession() { var session = new Session(); _accountSessionDataModel.Sessions.Add(session); _accountSessionDataModel.SaveChanges(); }
问题是我在创build会话(在代码中)后更新了前端中的会话,但因为SaveChangesAsyncasynchronous发生,所以读取会话导致了这个错误,因为显然SaveChangesAsync操作还没有准备好。
我在我的工具中使用Web服务,在那里获取存储过程的服务。 而更多的客户端工具提取Web服务时,则会出现此问题。 我通过指定这些函数的Synchronized属性来修复存储过程。 现在工作正常,错误从来没有出现在我的工具。
[MethodImpl(MethodImplOptions.Synchronized)] public static List<t> MyDBFunction(string parameter1) { }
该属性允许一次处理一个请求。 所以这解决了这个问题。
对于那些通过Google发现的问题;
我得到了这个错误,因为正如错误提示的那样,在创build另一个SqlCommand之前我没有closuresSqlDataReader,错误地认为在离开它创build的方法时它会被垃圾回收。
我通过调用sqlDataReader.Close();
来解决这个问题sqlDataReader.Close();
在创build第二个阅读器之前。
对我来说这是我自己的错误。 我试图运行一个INSERT
使用SqlCommand.executeReader()
当我应该使用SqlCommand.ExecuteNonQuery()
。 它被打开,从不closures,导致错误。 注意这个疏忽。
这是从现实世界的情景中提取的:
- 代码在Stage环境中运行良好,MultipleActiveResultSets在连接string中设置
- 在没有MultipleActiveResultSets = true的情况下发布到生产环境的代码
- 如此多的页面/呼叫工作,而单一的失败
- 仔细看看电话,有一个不必要的调用数据库,需要被删除
- 在Production中设置MultipleActiveResultSets = true,并发布清理后的代码,一切正常,效率很高
总而言之,在不遗忘MultipleActiveResultSets的情况下,代码在运行之前可能已经运行了很长时间,可能代价很高,而且我build议不要完全依赖于设置MultipleActiveResultSets属性,而是要找出为什么代码需要它失败的地方 。