1

我正在使用 EF5 POCO 实体(数据库首先不是代码,如果有区别的话)。假设我有以下(假设的)实体类型:-

  • 店铺
  • 客户(具有 StoreId 的 FK)
  • 产品(具有 StoreId 的 FK)
  • 订单(带有 CustomerId 和 ProductId 的 FK)

一个商店有很多客户和产品,一个订单基本上是客户和产品之间的一个 MM 连接。

我的一个典型场景涉及检索一个商店实体及其所有相关的客户、产品和订单。有了这个层次结构现在在内存中,用户可以选择通过 UI 删除客户。作为此操作的一部分,我还希望删除客户的相关订单。

这样做是否足够:-

store.Customers.Remove(customerToDelete);

或者是否也有必要在客户的订单和他们的产品之间“断开链接”,例如:-

foreach (var order in customerToDelete.Orders)
{
    order.Product.Orders.Remove(order);
}

请注意,更改不一定会立即保留回数据库。用户可以继续使用此内存存储层次结构,并且仅在稍后单击“保存”按钮时才保留更改。因此,如果他们继续通过 UI“浏览”这个实体层次结构,并深入了解特定产品,我不希望他们看到与已删除客户相关的订单。因此,我怀疑我必须执行上述foreach操作才能清除该客户订单的所有痕迹?

不确定它是否与我的问题有关,但有人可以解释“End1 OnDelete”EDMX 属性的作用吗?我了解级联删除在 SQL 中的工作原理,但不确定此 EDMX 级联选项适用于何处?

4

1 回答 1

0

上下文不会自动删除客户实体拥有的订单。通常,您将在 UI 中显示搜索结果的只读上下文:

DbSet.Where(x => x == y).AsNoTracking()

因此,当您从数据源中删除客户时,不会自动刷新,因为您将使用新的上下文进行更新。这种模式现在已被普遍接受,因为您不想处理从包含陈旧实体的上下文更新数据源而导致的不可避免的异常。最好为工作单元/范围内的一组操作创建一个新的上下文。

但是,您可以使用Fluent API设置级联删除

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Course>()
    .HasRequired(t => t.Department)
    .WithMany(t => t.Courses)
    .HasForeignKey(d => d.DepartmentID)
    .WillCascadeOnDelete(false);
}

这将完成从数据源中删除订单的工作,但是您通过 UI 可见的订单需要以某种方式刷新/删除。如果您的订单数据非常大,请考虑延迟加载,因为您可以推迟加载相关实体直到它们被实际访问,这很好,只要您知道自己在做什么并且在迭代集合时不会意外往返. 您在删除后手动删除实体的方法也很好,但是,不要忘记单独删除关系/链接,因为这会一直存在并可能导致问题。

于 2013-10-24T16:23:38.713 回答