通过导航属性从集合对象中删除对象时遇到了严重的性能问题。当调用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个物体。显然,这不是一个令人满意的通用解决方案。
答案 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 => ....);