【问题标题】:An exception occurred while iterating over the results of a query for context type. The connection is closed迭代上下文类型的查询结果时发生异常。连接已关闭
【发布时间】:2021-04-02 03:26:49
【问题描述】:

在运行 LINQ 查询期间出现以下错误

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

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

以下代码块产生错误

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

注意productCatalogToUpdate 是一个大的List&lt;Guid&gt;,大约有 7k 个 Guid

存储库实现:

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

注意 2:与上下文相关的所有内容都由原生 DI 处理,通过 AddDbContext&lt;T&gt;()

知道为什么会这样吗?

【问题讨论】:

  • @mjwills 这是问题所在,我无法在本地重现,只有在应用发布后才会出现错误
  • 再次阅读链接。简短的回答 - 您可能在 Web 请求的上下文之外使用 db 上下文。
  • Contains 在处理大量数据时速度非常慢。应该是超时了。试试this
  • 你说得对,@GertArnold,这解决了我的问题,非常感谢!

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


【解决方案1】:

@GertArnold 绝对正确,谢谢哥们!

问题是 .Contais() 接收大量项目的速度太慢,导致了这种奇怪的行为。为了解决这个问题,我按照@GertArnold 指出的答案引导我到另一个帖子。

策略是将大量项目分块并创建多个查询,这可能听起来很奇怪,许多查询会比单个查询运行得更快,但在采用该解决方案之前我已经做了一些基准测试,并且即使运行 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&lt;T&gt; 分解为较小的IEnumerable&lt;T&gt;。这个方法也是由@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;
    }
}

【讨论】:

    【解决方案2】:

    如果您的应用程序从未在 Azure 上运行过,最常见的问题是您的连接字符串格式。试试这个:

    Server=tcp:servername.database.windows.net,1433;Initial Catalog=db;Persist Security Info=False;
    User ID=user;Password=mypassword;
    MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
    

    【讨论】:

    • 我不认为问题在于 OP 无法连接到数据库。
    • 连接字符串没问题,除了这个查询一切正常
    猜你喜欢
    • 2023-02-02
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2013-09-11
    • 1970-01-01
    相关资源
    最近更新 更多