gpt4 book ai didi

C# Entity Framework 4 导航属性导致提交时性能下降

转载 作者:太空狗 更新时间:2023-10-29 17:58:39 26 4
gpt4 key购买 nike

对于这个问题中缺乏细节,我深表歉意 - 我需要帮助的第一件事是知道在哪里寻找更多细节。

我有一个 Entity Framework 4 导航属性的问题,显然在提交更改时导致性能不佳:

this.ObjectContext.SaveChanges();

当其中一个导航属性(收据表)包含大约 8000 行(数量不多,所以应该没问题)时需要 30 多秒。

我使用了 SQL 事件探查器,可以看到 EF 发出了一个 select * from Receipts 并且它非常慢:

exec sp_executesql N'SELECT 
[Extent1].[Id] AS [Id],
// full field list cut for brevity
FROM [dbo].[Receipts] AS [Extent1]
WHERE [Extent1].[WarehouseId] = @EntityKeyValue1',
N'@EntityKeyValue1 int',@EntityKeyValue1=1

目前我什至不明白为什么它需要在调用 ObjectContext.SaveChanges() 时从此表中选择所有行。

它确实需要向该表中插入 1 行,但这并不能解释为什么它首先进行全选 - 也不能解释为什么该选择需要这么长时间(同一查询在查询管理器中花费 < 1 秒)

所以我现在的问题 - 我还不完全知道问题是什么 - 是:

  • 我在哪里/如何查找有关该问题的更多详细信息?我无法调试到 ObjectContext.SaveChanges(),所以我不知道其中发生了什么。
  • 为什么 EF 会尝试从 Receipts 中选择 *?
  • 为什么这么慢?复制+粘贴到查询管理器中的完全相同的查询几乎是即时的

编辑:

我已经通过注释掉对此方法的调用来确认是收据代码变慢了:

    private void AddReceipt(PurchaseInvoice invoice, 
PurchaseInvoiceLine invoiceLine)
{
if (invoice != null && invoiceLine != null)
{
Product product = invoiceLine.Product;
if (product != null)
{
Receipt receipt = new Receipt{ foo = bar };
WarehouseDetail detail = new WarehouseDetail{ foo = bar };
receipt.WarehouseDetails.Add(detail);
invoice.Receipts.Add(receipt);
}
}
}

但我仍然不明白为什么这会导致 EF 发出该 select * 查询。

我认为这可能是由 invoice.Receipts.Add(receipt) 引起的延迟加载问题。因为在那行 invoice.Receipts 之前是空的,为了 .Add 到 Receipts,它必须首先加载集合。但这并不能解释为什么它按 warehouseId=1 选择,而它应该按 invoiceId 选择。

编辑 2:

我已通过将此方法中的 EF 代码替换为直接 SQL 命令来“修复”了该问题。这不是一个好主意——当我有一个非常好的 ORM 时,我不应该乱扔 SQL。但现在我仍然不明白为什么 EF 正在运行 select * 查询

    private void AddReceipt(PurchaseInvoice invoice, 
PurchaseInvoiceLine invoiceLine)
{
if (invoice != null && invoiceLine != null)
{
Product product = invoiceLine.Product;
if (product != null)
{
Receipt receipt = new Receipt{ foo = bar };
WarehouseDetail detail = new WarehouseDetail{ foo = bar };
int id = SqlHelper.AddWarehouseDetail(detail);
receipt.WarehouseDetailId = id;
SqlHelper.AddReceipt(receipt);
}
}
}

最佳答案

由于这是一个插入,它通过选择返回值并重新填充对象来刷新您的对象。现在让我回答您提出的问题:

  1. 您不需要调试而不是 SaveChanges(),您所看到的可能无论如何都没有多大意义。

  2. 它实际上并没有执行 select * from Receipts。它正在执行 select * from Receipts where WarehouseId = 1。因此出于某些原因,您反对提取 ID 为 1 的仓库的所有收据。

  3. 这可能取决于很多事情,您现在真的无法深入了解它。但一个起点是检查您的应用程序框和数据库框之间的 ping 速率。还要检查数据库框上的 RAM 是否已满。这就是我要开始的地方,也是您所描述内容的常见问题。

调试 EF 的一个好工具是 EF Profiler。 http://efprof.com这比 SQL 分析器对您的帮助要大得多。

关于C# Entity Framework 4 导航属性导致提交时性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5545780/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com