实体框架 CTP5,代码优先。多对多级联删除

Posted

技术标签:

【中文标题】实体框架 CTP5,代码优先。多对多级联删除【英文标题】:Entity Framework CTP5, code-first. Many to many with cascade delete 【发布时间】:2011-01-04 12:31:15 【问题描述】:

我有两个实体(Customer 和 CustomerRole),想声明它们之间的多对多关系。我可以使用以下代码:

modelBuilder.Entity<CustomerRole>()
        .HasMany(cr => cr.Customers) 
        .WithMany(c => c.CustomerRoles)
        .Map(m => m.ToTable("Customer_CustomerRole_Mapping"));

但它创建的关系(和第三个映射表)默认关闭级联删除。使用多对多时,如何告诉 EF 在打开级联删除的情况下创建关系?

【问题讨论】:

【参考方案1】:

从 CTP5 开始,似乎无法通过 Fluent API 直接打开多对多关联的级联删除。

也就是说,如果您的目的是确保您可以删除主体(例如客户记录)而不必担心连接表中的依赖记录(即 Customer_CustomerRole_Mapping),那么您不需要打开数据库上的级联,因为 EF Code First 将在客户端处理多对多关联时的级联删除。

例如,当你删除一个客户对象时,EF 很聪明,它会先发送一条删除语句来删除连接表中的依赖记录,然后再发送一条删除语句来删除客户记录。

更新:

由于 CTP5 中的错误,您需要显式急切/延迟加载导航属性,并在删除依赖项时将其加载到上下文中。例如,考虑这个模型:

public class User

 public int UserId  get; set; 
 public virtual ICollection Addresses  get; set; 


public class Address

 public int AddressID  get; set;  
 public virtual ICollection Users  get; set; 

假设我们在数据库中有一个带有地址的用户,这段代码会抛出:

using (EntityMappingContext context = new EntityMappingContext())

 User user = context.Users.Find(1); 
 context.Users.Remove(user);
 context.SaveChanges();

但是,这个可以完美地首先删除链接表的记录:

using (EntityMappingContext context = new EntityMappingContext())

 User user = context.Users.Find(1); 
((IObjectContextAdapter)context).ObjectContext
                                .LoadProperty(user, u => u.Addresses);
 context.Users.Remove(user);
 context.SaveChanges();

请注意,这只是一种解决方法,我们将能够(希望)在不加载其导航属性的情况下删除主体。

【讨论】:

不,似乎 EF 不够聪明,因为我收到以下异常:“DELETE 语句与 REFERENCE 约束“CustomerRole_Customers_Target”冲突。冲突发生在数据库“db_name_here”,表中“dbo.Customer_CustomerRole_Mapping”,列“CustomerId”。语句已终止。” 是的,你是对的,但在 CTP4 中就是这样,在 CTP5 中似乎有所改变。看到这个:***.com/questions/4158027/…。我会调查此问题并尽快回复您。敬请期待! 由于某种原因,我无法再重现异常!您能否发布您的代码以及您的对象模型? Morteza,我找到了答案。我也在 MSDN 论坛上问过同样的问题。你可以在这里找到它和“答案” - social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/… 好的,我可以看到 Zeeshan 提供了几乎相同的答案,只是他急切地通过 Include 方法加载导航属性。那么这就是解决您问题的方法吗?这意味着如果你不包含它就会抛出?

以上是关于实体框架 CTP5,代码优先。多对多级联删除的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF 代码优先中禁用链接表的级联删除?

实体框架代码优先建模问题

MyBatis一对多级联查询

实体框架 CTP5,代码优先。可选的导航属性

实体框架代码优先 CTP5:如何定义非原始类型

休眠 - 多对多关系中的级联删除