【问题标题】:Trouble with performance using EF6 many-to-many使用 EF6 多对多的性能问题
【发布时间】:2013-11-26 11:48:02
【问题描述】:

在使用 EF6 (6.0.1) 执行 INSERT 时,我发现生产速度极慢(从 30 到 120 秒不等)。我在设备和触发器之间有多对多的关系。 Device 有一个虚拟 ICollection,Trigger 有一个虚拟 ICollection。触发器,大部分是静态表(目前只有一行)。当我需要创建一个新设备时,我还需要创建一个到单个触发器行的映射。所以我快速搜索该行并执行 device.Triggers.Add()。但随着 EF6 深入到 ObjectStateManager.UpdateRelationships 和 ObjectStateManager.TryUpdateExistingRelationships 等函数,这似乎需要很长时间。我假设它正在更新我的 Trigger 实例下的所有设备。我该如何防止这种情况发生?有没有更好的方法来做我想做的事情?

谢谢, 时间

更新:好的,我找到了一种可能的解决方法。如果我删除关系的 Trigger-to-Device 端(即从 Trigger 中删除 ICollection),因为我真的不需要它,然后使用 fluent 方法设置它,如下所示:

modelBuilder.Entity<Device>()
    .HasMany(x => x.Triggers)
    .WithMany()
    .Map(x =>
    {
        x.MapLeftKey("Device_Id");
        x.MapRightKey("Trigger_Id");
        x.ToTable("TriggerDevices");
    });

但看来我不应该这样做。任何人都可以对此有所了解吗?

【问题讨论】:

  • 蒂姆,只是重复我在Codeplex 中所说的话:我们尝试复制您在此处描述的场景,但我们无法获得您报告的任何结果,所以如果您能提供我们将不胜感激完整的复制品。

标签: entity-framework entity-framework-6


【解决方案1】:

当数据库访问需要这么长时间时,通常是由于等待超时的锁,而不是数据库做了很多工作。

你可以检查:

  • 数据库锁。
  • 使用 SQL Profiler 查看您向数据库发送的请求。
  • 您的连接字符串中是否有“MultipleActiveResultSets=True”,如果缺少它可以解释锁定。

【讨论】:

  • 感谢您的回复,但我不认为我的问题出在这些问题上。我的连接字符串中有“MultipleActiveResultSets=true”。我查看了分析器,没有长时间运行的查询或锁定。而且我能够在我的本地机器上重现它(针对我的本地 SQL Server 运行),而没有其他活动。我使用 dotTrace 告诉我,所有时间都花在了我在 OP 中提到的功能上。这可能很明显,但随着我的 Device 表变大(目前大约有 25k 行),情况变得更糟。
【解决方案2】:

请接受这是我的第一篇文章 - 如有任何礼仪错误,我们深表歉意。

我刚刚在生产系统中遇到了同样的问题;解决方案是反转添加。

为了这个例子:-

Triggers 有 1 行,Devices 有 100,000 行,实体框架上下文对象称为“db”

如果您将新设备添加到触发器,则使用

    var trigger = db.Triggers.Single(t => t.ID == <triggerID> );
    trigger.devices.add(newDevice);

ef 将加载整个设备集合(您有很多设备连接到您的一个触发器),以便它可以对对象触发器的 ICollection 设备属性执行更改跟踪。

但是,如果您使用 newDevice.Triggers.add(exitingTrigger) 则 ef 不会从源加载任何数据,更改跟踪知道要创建 newDevice,并且列表中只有一项,即使 ef确实想查询来源。

我是少数几个在 EF 文档中错过这一点的人之一吗?

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2015-07-18
    • 2017-12-10
    • 2013-04-28
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多