如何级联删除使用实体框架code首先流利的API仅在连接表 [英] How to cascade delete only on join table using Entity Framework Code First Fluent API

查看:104
本文介绍了如何级联删除使用实体框架code首先流利的API仅在连接表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用映射实体框架code首先流利的API现有的数据库。我挣扎的情况下有很多一对多的关系,级联删除。

下面是我的两个POCO类:

 公共类Foo
{
  公众诠释FooId;
  公共字符串FooDescription;
  公众的IList<酒吧GT;酒吧;
}
公共类酒吧
{
  公众诠释BarId;
  公共字符串BarDescription;
}
 

现在,我只有从导航属性为酒吧。这是因为,在我的现实情况下,这是没有意义的,任何人从酒吧。从酒吧的关系居然是0,N这意味着富<一个实例/ code>不需要酒吧

实例

我的现有数据库的连接这两个表之间的表。此表是这样的:

 创建表foo_bar这样的名称(
FooId诠释不为空,
BarId诠释不为空
);
 

由于我preFER在我的项目不建立这样一个POCO类,我映射表是这样的:

  modelBuilder.Entity&LT;富&GT;()
  .HasMany(T =&GT; t.Bars)
  .WithMany()
  .MAP(米=&GT;
  {
    m.ToTable(foo_bar这样);
    m.MapLeftKey(FooId);
    m.MapRightKey(BarId);
  });
 

这完全适用于刀片。关于美孚,然后在实体插入现有的 foo_bar这样的名称表。

但是,当我删除,我想删除的连接表,但没有子表中的记录。这意味着我要删除记录的 foo_bar这样的名称而不是这个级联扩展到酒吧

就是这样的映射可能吗?我要指出,在我的情况下我删除了这两个 OneToManyCascadeDeleteConvention ManyToManyCascadeDeleteConvention ,因为99%的时间我不会使用级联删除。这是一个特定的情况。

通过跟踪由实体框架生成的SQL,我也注意到,如果我取回实例,并设置所有的酒吧里面,以EntityState.Deleted,EF将同时删除在 foo_bar这样的名称记录和酒吧。最后一件事我应该提到的是,我在断开连接的情况下我的工作。

我试图寻找该结束了,但好像我不使用正确的关键字,因为我找不到任何人在这种情况下。在这一点上,我看到的唯一的解决办法是地图 A FooBar的类,但我希望有一种方法做这一点。

- 修改

看来,我的方法来删除是错误的在第一。当我试图删除我是不及格的实例与酒吧填充的名单。这一变化后,实体Framwork创建一个delete语句,每酒吧的名单上。我仍然有问题的更新比如增加或减少在同一时间的项目。会做更多的测试,并张贴在这里。

在此先感谢。

解决方案
  

但是,当我删除一个Foo,我想删除的记录   加入的子表的表,但不是。这意味着我要删除   在fo​​o_bar这样的名称记录,但没有到这个级联扩展到吧。

     

就是这样的映射可能吗?

这是实际的唯一的映射是可能的。不能扩展级联删除到酒吧表,因为在关系(从数据库架构的角度来看)的 foo_bar这样的名称加入表中的依赖的的关系和酒吧主要的。一般来说cacscading删除仅在生效,如果删除了主,但不是当你删除依赖。

所以,你不必担心,酒吧当你删除可以删除一个和你不必申请这个任何特殊的设置。

但是,你有,当你已经删除了 ManyToManyCascadeDeleteConvention 的一个问题。它的作用在全球范围为整个造型并没有选项可启用级联删除再为特定多对一对多的关系。 (有没有 WillCascadeOnDelete(真)对于很多一对多的关系像有一对一,一对多或一对一的一对一的关系。)

您确定删除 ManyToManyCascadeDeleteConvention 确实需要在你的模型?我从来没有遇到过一个模型,它将使意义的没有的删除相关条目的时候,加入了实体之一(或连接表酒吧)将被删除。

I'm trying to map an existing database using Entity Framework Code First Fluent API. I'm struggling on a situation with a many-to-many relationship and cascade delete.

Here's my two POCO classes:

public class Foo
{
  public int FooId;
  public string FooDescription;
  public IList<Bar> Bars;
}
public class Bar
{
  public int BarId;
  public string BarDescription;
}

For now, I only have a navigation property from Foo to Bar. That's because in my real scenario, it doesn't make sense for anyone to go from Bar to Foo. The relationship from Foo to Bar is actually 0,n which means one instance of Foo do not require instances of Bar.

My existing database has a join table between those two tables. This table looks like this:

create table Foo_Bar(
FooId int not null,
BarId int not null
);

Because I prefer to not create such a POCO class in my project, I mapped the table like this:

modelBuilder.Entity<Foo>()
  .HasMany(t => t.Bars)
  .WithMany()
  .Map(m =>
  {
    m.ToTable("Foo_Bar");
    m.MapLeftKey("FooId");
    m.MapRightKey("BarId");
  });

That works perfectly for inserts. Entity insert on Foo and then on the existing Foo_Bar table.

But when I delete a Foo, I would like to delete the records on the join table but not on the child table. Meaning I want to delete records on Foo_Bar but not to extend this cascade to Bar.

Is such a mapping possible? I should mention that on my context I removed both OneToManyCascadeDeleteConvention and ManyToManyCascadeDeleteConvention because 99% of the times I won't be using cascade delete. This is one specific situation.

By tracing the SQL generated by Entity Framework, I also noticed that if I retrieve a Foo instance and set all Bars inside it to EntityState.Deleted, EF will delete both records in Foo_Bar and Bar. One last thing I should mention is that I'm working in a disconnected scenario.

I tried to search this over but it seems I'm not using the right keywords as I could not find anyone in such a situation. At this point the only solution I see is to Map a FooBar class but I'd hope there's a way to do this.

--Edit

It appears that my approach to delete was wrong at first. When I tried deleting I wasn't passing the instance of Foo with its list of Bar filled. After that change, Entity Framwork creates a delete statement for every Bar on the list. I still have problems with updating like adding and removing items at the same time. Will do more tests and post here.

Thanks in advance.

解决方案

But when I delete a Foo, I would like to delete the records on the join table but not on the child table. Meaning I want to delete records on Foo_Bar but not to extend this cascade to Bar.

Is such a mapping possible?

This is actually the only mapping that is possible. You cannot extend cascading delete to the Bar table because in the relationship (from database schema perspective) the Foo_Bar join table is the dependent in the relationship and Bar is the principal. Generally cacscading delete is only in effect if you delete the principal but not when you delete the dependent.

So, you don't need to worry that a Bar could be deleted when you delete a Foo and you don't have to apply any special setting for this.

But you have a problem when you have removed the ManyToManyCascadeDeleteConvention. It acts globally for the whole model and there is no option to turn on cascading delete again for a specific many-to-many relationship. (There is no WillCascadeOnDelete(true) for many-to-many relationship like there is one for one-to-many or one-to-one relationships.)

Are you sure that removing the ManyToManyCascadeDeleteConvention is really required in your model? I never encountered a model where it would make sense to not delete the related entries in the join table when one of the joined entities (Foo or Bar) is deleted.

这篇关于如何级联删除使用实体框架code首先流利的API仅在连接表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆