让我们说我有实体A,它与A类型的另一个实体有很多很多关系。所以在实体A上,我有A的集合。并且让我说我必须根据一些外部服务“更新”这种关系 - 我不时收到某个实体的关系发生变化的通知,以及当前相关实体的ID数组 - 某些关系可能是新的,有些是现有的,有些现有的不再存在...我怎样才能有效地更新我的数据库与EF? 一些想法:
渴望加载实体及其相关实体,预先从外部服务收集ID,并根据需要删除/添加。但这不是很有效 - 需要加载可能数百个相关实体
清除当前关系并插入新内容。但是怎么样?也许通过存储过程执行删除,然后通过“假”对象插入
a.Related.Add(new A { Id = idFromArray })
但这可以在交易中完成吗? (调用存储过程,然后通过SaveChanges
完成插入)
还是有第三种方式?
感谢名单。
答案 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都进入,并且存储过程在事务中执行删除和插入。
在这里查看示例和性能比较(很棒的文章,基于我的解决方案):