0

在使用 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");
    });

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

4

2 回答 2

0

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

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

为了这个例子: -

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

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

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

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

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

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

于 2014-03-06T14:46:14.827 回答
0

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

你可以检查:

  • 数据库锁。
  • 用户 SQL Profiler 查看您发送到数据库的请求。
  • 您的连接字符串中是否有“MultipleActiveResultSets=True”,如果缺少它可以解释锁。
于 2013-11-13T18:57:59.190 回答