c# - 迭代上下文类型的查询结果时发生异常。连接已关闭

标签 c# sql-server azure entity-framework-core

我在 LINQ 查询运行期间收到以下错误

An exception occurred while iterating over the results of a query for context type. The connection is closed

奇怪的是,只有当应用程序在 Azure 上发布时才会发生这种情况(Db 也在 Azure 中),一切都像魅力一样工作

以下代码块会生成错误

List<StoreProductCatalogPrice> pricesToUpdate = await _storeProductCatalogPriceRepository.GetCurrentByProductCatalogId(productCatalogToUpdate);`

注意:productCatalogToUpdate是一个大List<Guid>大约有 7k 个指南

存储库实现:

public async Task<List<StoreProductCatalogPrice>> GetCurrentByProductCatalogId(List<Guid> productCatalogsIds)
{          
    return await DbSet.Where(x => productCatalogsIds.Contains(x.StoreProductCatalogId)).ToListAsync();
}

注释 2:与上下文相关的所有内容均由 native DI 处理,通过 AddDbContext<T>()

知道为什么会发生这种情况吗?

最佳答案

@GertArnold 绝对正确,谢谢伙计!

问题是 .Contais() 接收大量项目的速度太慢,导致了这种奇怪的行为。为了解决这个问题,我遵循了 @GertArnold 指出的答案,这将我带到了另一篇文章。

该策略是将大量项目分解为 block 并最终创建多个查询,许多查询比单个查询运行得更快可能听起来很奇怪,但在采用该解决方案之前我已经做了一些基准测试,并且事实证明,即使运行 14 个查询(在我的例子中)而不是单个查询,代码也会快 30% 左右。

这是最终的代码:

public async Task<List<StoreProductCatalogPrice>> GetCurrentByProductCatalogId(List<Guid> productCatalogsIds)
{
    var chunks = productCatalogsIds.ToChunks(500);
    return chunks.Select(chunk => DbSet.Where(c => chunk.Contains(c.StoreProductCatalogId))).SelectMany(x => x).ToList();
}

此扩展方法破坏了单个 IEnumerable<T>根据您通过参数传递的数量来划分较小的。此方法也由 @GertArnold 发布(再次感谢),可以在此处找到

public static IEnumerable<IEnumerable<T>> ToChunks<T>(this IEnumerable<T> enumerable, int chunkSize)
{
    int itemsReturned = 0;
    var list = enumerable.ToList(); // Prevent multiple execution of IEnumerable.
    int count = list.Count;
    while (itemsReturned < count)
    {
        int currentChunkSize = Math.Min(chunkSize, count - itemsReturned);
        yield return list.GetRange(itemsReturned, currentChunkSize);
        itemsReturned += currentChunkSize;
    }
}

关于c# - 迭代上下文类型的查询结果时发生异常。连接已关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65425412/

相关文章:

c# - Bot framework v4.0 如何在对话中执行前面的瀑布步骤

c# - 在 C# 中,SerialPort 类的 DataReceived 事件处理程序是否在它自己的线程上执行?

sql - 在同一 SQL 查询中匹配多个值

sql-server - 使用 ADF Pipeline 中的自定义事件从 OnPrem SQL Server 复制到 DocumentDB

azure - 从 customDimensions 中的 json 扩展数据

c# - 如何从 AppSettings 读取配置值并将配置注入(inject)接口(interface)实例

c# - 如何在 Android 上接收 RemObjects 事件?

c# - 检索 SQL Server 中表的 DataTable 信息

python - 如何使用office365-rest-python-api从sharepoint下载文件

azure - 来自 Azure 服务总线监听器的错误 "Exception while executing function"