2012-04-24 88 views
2

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

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

没有参与太多自己的代码,即通过(生成的代码)

RelationshipManager.GetRelatedCollection<...>(<relationShipName>, <targetRoleName>) 

和实际删除创建的EntityCollection是一个简单的

EntityCollection<Type>.Remove 

一个电话我怀疑的EntityFramework在进行实际删除之前加载所有65.000个对象。 到目前为止,但我还没有能够证明这一假设。

任何想法?

感谢 弗兰克

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

我找到了一种解决方法,并使用关系的较小的一面,即当我想从对象A到对象B去除关系时,当对象A具有65000个对象时,我从对象B侧移除关系,表现没问题,因为对象B只与例如10个对象。很明显,这不是一个令人满意的通用解决方案。

回答

1

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

只要删除对象,如果需要获取此导航属性,则可以在EntityReference上使用CreateSourceQuery。如果您的导航属性名为Candles,那么EntityReference将被默认调用CandlesReference。所以,你缺失是这样的:

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

这将让本来会执行查询,并给你一个机会,只是摘掉一个你想要的,而不必首先抓住一切。

假设你有必要的信息,它可能是更有效的直接询问,如

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

喜马修,感谢您的答复,我但是不知道如果我理解正确。您建议使用CreateSourceQuery,然后调用DeleteObject删除找到的对象。然而,我的问题是我想删除一个关系而不是相关的对象。我也已经有两个对象需要删除关系。请澄清,如果我误解了你,谢谢弗兰克 – FrankE 2012-04-25 11:04:03

+0

嘿弗兰克,我正在处理删除/删除同义词,但我明白你的意思了。从您的编辑中,听起来这是一种多对多的关系。为了改进和保持性能,我认为你需要做的是让EF将连接表显示为实体,然后使用A和B的ID从连接表(关系)中获取单个实体,并删除它。你正在使用哪种方法(先编码,先模型,先数据库)? – 2012-04-25 12:48:29