使用EF6多对多的性能问题

时间:2013-11-13 18:08:45

标签: entity-framework entity-framework-6

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

谢谢, 添

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

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

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

2 个答案:

答案 0 :(得分:0)

当数据库访问花费很长时间时,通常是由于等待超时的锁而不是数据库执行大量工作。

您可以查看:

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

答案 1 :(得分:0)

请接受这是我的第一篇文章 - 抱歉任何礼仪错误。

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

为了这个例子: -

触发器有1行,设备有100,000行,实体框架上下文对象叫做“db”

如果您使用

将新设备添加到触发器
    var trigger = db.Triggers.Single(t => t.ID == <triggerID> );
    trigger.devices.add(newDevice);

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

但是如果你使用newDevice.Triggers.add(exitingTrigger),那么ef将不会从源加载任何数据,更改跟踪知道要创建newDevice,并且列表中只有一个项目,无论如何,即使ef我想查询来源。

在EF文档中,我是少数几个想念它的人之一吗?