实体框架 CTP5,代码优先。具有级联删除功能的多对多

发布于 2024-10-10 22:01:42 字数 346 浏览 3 评论 0原文

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

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

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

I have two entities (Customer and CustomerRole) and would like to declare many-to-many relationship between them. I can do using the following code:

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

But it creates the relationship (and the third mapping table) with cascade delete switched off by default. How can I tell EF to create the relationship with cascade delete switched on when using many-to-many?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我要还你自由 2024-10-17 22:01:42

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

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

例如,当您删除一个Customer对象时,EF足够聪明,首先发送一条删除语句来删除连接表中的依赖记录,然后它会发送另一个删除语句来删除该Customer记录。

更新:

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

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

As of CTP5, there seems to be no way to directly turn on cascade deletes on Many to Many associations by Fluent API.

That said, if your intention is to make sure that you can delete the principal (e.g. a Customer record) without having to worry about the dependent record in the join table (i.e. Customer_CustomerRole_Mapping) then you don't need to turn on cascades on the database since EF Code First will take care of the cascade deletes on the client side when it comes to Many to Many associations.

For example, when you delete a Customer object, EF is smart enough to first send a delete statement to get rid of the dependent record in the join table and after that it will send another delete statement to delete the Customer record.

Update:

Due to a bug in CTP5, you need to explicitly eager/Lazy load the navigation property and have it loaded on the context when you remove the dependent. For example, consider this model:

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

Assuming that we have a User with an address in the database, this code will throw:

using (EntityMappingContext context = new EntityMappingContext())
{
 User user = context.Users.Find(1); 
 context.Users.Remove(user);
 context.SaveChanges();
}

However, this one will perfectly work with removing the link table's record first:

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

Please note that this is just a workaround and we will be able to (hopefully) remove a principal without loading its navigation property.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文