如何有效地刷新多对多的关系

时间:2011-10-16 14:05:58

标签: sql entity-framework entity-framework-4

让我们说我有实体A,它与A类型的另一个实体有很多很多关系。所以在实体A上,我有A的集合。并且让我说我必须根据一些外部服务“更新”这种关系 - 我不时收到某个实体的关系发生变化的通知,以及当前相关实体的ID数组 - 某些关系可能是新的,有些是现有的,有些现有的不再存在...我怎样才能有效地更新我的数据库与EF? 一些想法:

  1. 渴望加载实体及其相关实体,预先从外部服务收集ID,并根据需要删除/添加。但这不是很有效 - 需要加载可能数百个相关实体

  2. 清除当前关系并插入新内容。但是怎么样?也许通过存储过程执行删除,然后通过“假”对象插入

    a.Related.Add(new A { Id = idFromArray })
    
  3. 但这可以在交易中完成吗? (调用存储过程,然后通过SaveChanges完成插入)

    还是有第三种方式?

    感谢名单。

2 个答案:

答案 0 :(得分:0)

嗯,“不时”听起来不像是一种考虑性能提升的情况(除非你的意思是“从毫秒到毫秒”):)

无论如何,第一种方法是在没有存储过程的情况下进行此更新的正确想法。是的,您必须加载所有旧的相关实体,因为更新多对多关系只会通过EF更改检测。在没有加载导航属性的情况下,没有可用于更新关系的外显外键。

这里可能会详细介绍一个例子(昨天的新问题):

Selecting & Updating Many-To-Many in Entity Framework 4

(只有“编辑”部分之前的最后一个代码段与您的问题和编辑部分本身相关。)

对于第二个解决方案,您可以将整个操作包装到手动创建的事务中:

using (var scope = new TransactionScope())
{
    using (var context = new MyContext())
    {
        // ... Call Stored Procedure to delete relationships in link table

        // ... Insert fake objects for new relationships

        context.SaveChanges();
    }
    scope.Complete();
}

答案 1 :(得分:0)

好的,找到了解决方案。当然,纯EF解决方案是原始问题中提出的第一个解决方案。

但是,如果性能很重要,那么第三种方式是最好的方式,尽管它是SQL服务器特定的(afaik) - 一个具有表值参数的过程。所有新的相关ID都进入,并且存储过程在事务中执行删除和插入。

在这里查看示例和性能比较(很棒的文章,基于我的解决方案):

http://www.sommarskog.se/arrays-in-sql-2008.html