gpt4 book ai didi

C# .NET 4.6.1 Entity Framework - DB.MyTable.Add(...) 很慢,尽管没有调用 DB.SaveChanges()

转载 作者:行者123 更新时间:2023-12-04 08:37:41 24 4
gpt4 key购买 nike

(一) 这个版本是 ... 持续时间以多分钟为单位

  • DB 是 SQL 服务数据库的典型 EF 数据上下文
  • AA_Words_100是添加到 EF 设计器的简单 SQL Server 表
  • DB.AA_Words_100.Add被调用约 3,000 次(通过使用计数器变量调试确认)
  • 我已经确认 >99% 的运行时间在内部循环内
  • XCampaignDictionary<string, Dictionary<string, _Word>>其中 _Word 是一个普通的非 EF 对象。
  • foreach (var XCampaign in Words100)
    foreach (var KVP in XCampaign.Value)
    DB.AA_Words_100.Add(KVP.Value.To_AA_Word_100());

    DB.SaveChanges();
    (B) 这个版本是 ... - .Add()被简单地注释掉以缩小范围
    var iTemp = 0;

    foreach (var XCampaign in Words100)
    foreach (var KVP in XCampaign.Value)
    iTemp++;

    DB.SaveChanges();
    (三) 这个版本是 .我只是在调用 DB.AddRange(...) 之前填写了一个列表。
    var LIST_WordsToAdd = new List<AA_Words_100>();

    foreach (var XCampaign in Words100)
    {
    foreach (var KVP in XCampaign.Value)
    {
    LIST_WordsToAdd.Add(KVP.Value.To_AA_Word_100());
    }

    DB.AA_Words_100.AddRange(LIST_WordsToAdd);
    }

    DB.SaveChanges();
    (四) 文档
    根据 DbContext.Add documentation

    Begins tracking the given entity, and any other reachable entities that are not already being tracked, in the Added state such that they will be inserted into the database when SaveChanges() is called.


    特别是当 SaveChanges()叫做。
    我最近在此应用程序中从 Linq-to-SQL 迁移到 EF。 Linq-to-SQL 没有这个问题。 DB.AA_Words_100.Add(...) 有什么原因?命令这么慢?
    谢谢!
    #Update - To_AA_Word_11() 代码
    public AA_Words_100 To_AA_Word_100()
    {
    var W = new AA_Words_100();
    W.Word = Word;
    W.Word_Clean = Word.Replace("'", "");
    W.PhraseCount = PhraseCount;
    W.Clicks = Clicks;
    W.Impressions = Impressions;
    W.SalesAmt = SalesAmt;
    W.SalesOrders = SalesOrders;
    W.SalesUnits = SalesUnits;
    W.Spend = Spend;
    W.Campaign = Campaign;
    return W;
    }


    最佳答案

    如评论中所述 - Entity Framework (不确定 Entity Framework 核心)默认调用 DetectChanges在每个 Add .除其他外,此功能会扫描已被上下文跟踪的所有实体,以检测它们内部和之间的变化。这意味着该函数的时间复杂度为 O(n),其中 n 是上下文已跟踪的实体数。当您在循环中进行大量添加时 - 时间复杂度变为 O(n^2),其中 n 是添加的项目总数。因此,即使只有 3000 行这样的小数字,性能也会显着下降。
    要解决这个(有争议的设计)问题,有几个选项:

  • 将上下文的 AutoDetectChangesEnabled 设置为 false .然后手动调用DetectChanges之前 SaveChanges .
  • 或使用 AddRange它调用 DetectChanges,而不是一一添加实体就一次。

  • 另一个注意事项:
  • 尽量避免在操作之间重用上下文。你说在你调用第一个 Add 之前已经有 3000 个实体被上下文跟踪。每次需要时最好创建新的上下文,做这些事情,然后处理它。性能影响可以忽略不计(并且连接由连接池管理,每次创建\处置上下文时都不必打开或关闭),但是像这样的问题会少得多(重用上下文不仅会在您现在有,但在其他几个)。
  • 使用AsNoTracking如果您不打算修改特定查询返回的实体(或者如果您打算稍后通过附加到上下文来修改其中一些实体),则查询。然后上下文将不会跟踪它们,这将减少提及和其他性能问题的可能性。

  • 至于 Linq To Sql - 它具有类似的“检测更改”概念,但仅在将更改提交到数据库之前自动调用,而不是在每次添加时自动调用,因此您不会在那里看到相同的问题。

    关于C# .NET 4.6.1 Entity Framework - DB.MyTable.Add(...) 很慢,尽管没有调用 DB.SaveChanges(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64721708/

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