> 故障排除“已经有一个打开的dataReader ...”实体框架中的错误 这个错误,“已经有一个与此命令关联的开放数据标准器必须首先关闭,”通常在尝试执行数据库查询时会出现,而另一个查询的结果仍在处理。 让我们检查一个常见的方案及其解决方案。
这个问题通常源自嵌套查询,其中一种方法在较大的查询迭代中执行数据库查询。 例如,考虑
方法:>
DateLastUpdated
<code class="language-csharp">public DateTime DateLastUpdated(long creditorRegistryId, string accountNo) { return (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); }</code>
LastUpdated
<code class="language-csharp">return accounts.AsEnumerable() .Select((account, index) => new AccountsReport() { // ... other properties ... DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber); // ... other properties ... }) // ... rest of the query ...</code>
Select
DateLastUpdated
1。启用多个活动结果集(MARS)
最简单的解决方案通常是在连接字符串中启用火星。 这允许多个活动数据读取器同时进行。 修改您的连接字符串以包括
:
>>警告:MultipleActiveResultSets=True
<code class="language-csharp">connectionString = "Data Source=myServerAddress;Initial Catalog=myDatabase;MultipleActiveResultSets=True;";</code>
>更有效,通常优先的方法是急切的加载。 而不是嵌套查询,而是使用Entity Framework的
方法在单个查询中获取所有必需的数据:这个单个查询检索
,和Include
>数据,消除了对多个数据读取器的需求并解决了错误。 急切的加载可以通过减少到数据库的往返来提高性能。 请记住调整
<code class="language-csharp">var accounts = from account in context.Accounts .Include(a => a.AccountHistory) // Eager load AccountHistory .Include(a => a.Gurantors) // Eager load Gurantors select new AccountsReport { // ... other properties ... DateLastUpdated = account.AccountHistory.Max(h => h.LastUpdated), // ... other properties ... };</code>
>
在火星和急切的加载之间进行选择取决于您应用程序的特定需求和查询复杂性。 通常建议使用急切的加载以提高性能和更清洁的代码,但是如果重构查询不可行,火星可以快速解决。Accounts
>
以上是为什么我会在我的C#代码中获得'已经有一个打开的dataReader ...”错误,我该如何修复?的详细内容。更多信息请关注PHP中文网其他相关文章!