EntityFramework:EntityCollection.Remove具有严重的性能问题

时间:2012-04-24 10:47:36

标签: entity-framework

通过导航属性从集合对象中删除对象时遇到了严重的性能问题。当调用EntityCollection.Remove时,需要8分钟(!!!!)才能完成

详细说明: CollectionObject X有65.000个对象。只应从集合中删除其中一个。

涉及的代码不多,即EntityCollection是通过(生成的代码)

创建的
RelationshipManager.GetRelatedCollection<...>(<relationShipName>, <targetRoleName>)

,实际删除只是一个

的调用
EntityCollection<Type>.Remove

我怀疑EntityFramework在进行实际删除之前加载了所有65.000个对象。 到目前为止,我无法证明这一假设。

有什么想法吗?

由于 弗兰克

其他信息: 我找到了这个有用的链接: EF builds EntityCollection, but I (think I) want IQueryable 问题的真正原因是执行删除时EntityCollection的行为。

我找到了一种解决方法并使用了关系的较小一面,即当我想删除从对象A到对象B的关系时,当对象A有65000个对象时,我从对象B侧删除关系,性能还可以,因为对象B仅与例如相关10个物体。显然,这不是一个令人满意的通用解决方案。

1 个答案:

答案 0 :(得分:1)

是的,它可能在执行删除之前加载所有对象。您可以使用SQL Server附带的SQL事件探查器工具来验证这一点。

就移除对象而言,如果需要获取此导航属性,则可以在EntityReference上使用CreateSourceQuery。如果您的导航属性称为Candles,则默认情况下将调用EntityReference CandlesReference。所以你的删除看起来像这样:

var victim = entity.CandlesReference.CreateSourceQuery().Single(c => .....);
context.DeleteObject(victim);
context.SaveChanges();

这将获得本已执行的查询,并让您有机会选择所需的查询,而无需先获取所有内容。

假设您有必要的信息,直接查询可能更有效,例如

var victim = context.Candles.Single(c => ....);