【问题标题】:Deleting all related entities in Entity Framework删除实体框架中的所有相关实体
【发布时间】:2012-03-29 17:51:55
【问题描述】:

我有一个名为 Entry 的实体连接到多个 TimeWindows。我想清除所有时间窗口,然后添加新的。一开始我试过:

target.TimeWindows.Clear();

但这并没有真正删除它们,只是试图删除关系,这导致异常,因为从 TimeWindows 到 Entry 存在外键。然后我想我应该这样做:

foreach (var tw in target.TimeWindows)
    context.DeleteObject(tw);

但这也会引发异常,因为集合是在 foreach 语句中修改的。于是我想到了这个:

while (target.TimeWindows.Count > 0)
    context.DeleteObject(target.TimeWindows.Last());

但现在我有点担心使用Count 属性,因为它可能会导致执行SQL SELECT COUNT 语句。可以?如果是,如何删除 Entity Framework 中的所有时间窗口?

【问题讨论】:

  • 不,Count 不会在数据库上触发SELECT COUNT,更糟糕的是:-)。它将执行SELECT * FROM TimeWindows WHERE TargetId = @P0 并对内存中的集合进行计数。
  • 天哪!那你有什么建议?!
  • 当你想删除一个实体时,应该首先将它加载到内存中。所有的 O/RM 工具都以这种方式工作。实体框架也不例外。如果性能太低,请编写一个执行删除的存储过程。

标签: entity-framework


【解决方案1】:

仅当启用延迟加载且该属性尚未加载时,对导航属性调用计数才会导致选择。所以第一次调用可能会导致类似:

SELECT * FROM TimeWindows WHERE TargetId = @targetId

所有计数评估将只对加载的数据执行。

你也可以用这个来避免第二个异常:

foreach (var tw in target.TimeWindows.ToList())
    context.DeleteObject(tw);

或者您可以更改您的数据库和模型以支持identifying relation(FK 到父级将成为 TimeWindow PK 的一部分),在这种情况下您的第一个代码 sn-p 将起作用。

【讨论】:

  • 但是执行 ToList() 意味着获取所有时间窗口,对吧?!好吧,如果这是对的,那么实际上情况会更糟:-)
  • 在SQL中,我真的可以执行一条语句并删除所有时间窗口,类似于DELETE * FROM TimeWindows WHERE EntryId = ...,那么在Entity Framework中是否可以这样做?
  • 执行ToList 只会获取一次数据。如果没有little hacking,则无法进行批量删除,但是当使用这种方法时,在数据库中执行的更改将不会反映在您的上下文中。
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多