首页 >后端开发 >C++ >为什么我会在我的C#代码中获得'已经有一个打开的dataReader ...”错误,我该如何修复?

为什么我会在我的C#代码中获得'已经有一个打开的dataReader ...”错误,我该如何修复?

Susan Sarandon
Susan Sarandon原创
2025-01-29 21:51:09949浏览

Why Am I Getting the

> 故障排除“已经有一个打开的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

>语句调用的每次迭代,打开一个新的数据读取器。 在不关闭这些读者的情况下,随后的数据库操作失败了,导致“打开的dataReader”错误。
<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>
存在两个主要解决方案:

SelectDateLastUpdated 1。启用多个活动结果集(MARS)

最简单的解决方案通常是在连接字符串中启用火星。 这允许多个活动数据读取器同时进行。 修改您的连接字符串以包括

>

>警告:火星可以引入性能开销,并不总是理想的解决方案,尤其是在复杂的查询中。MultipleActiveResultSets=True

<code class="language-csharp">connectionString = "Data Source=myServerAddress;Initial Catalog=myDatabase;MultipleActiveResultSets=True;";</code>
2。实施急切的加载

>更有效,通常优先的方法是急切的加载。 而不是嵌套查询,而是使用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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn