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

时间:2011-01-04 12:31:15

标签: asp.net entity-framework-4 code-first

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

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

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

1 个答案:

答案 0 :(得分:8)

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

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

例如,当您删除Customer对象时,EF足够聪明,可以首先发送一个删除语句来删除连接表中的依赖记录,之后它将发送另一个删除语句来删除Customer记录。 / p>

更新

由于CTP5中存在错误,您需要显式eager / Lazy加载导航属性,并在删除依赖项时将其加载到上下文中。例如,请考虑以下模型:

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();
}

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