如何级联删除使用实体框架code首先流利的API仅在连接表 [英] How to cascade delete only on join table using Entity Framework Code First Fluent 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,我想删除的记录 加入的子表的表,但不是。这意味着我要删除 在foo_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屋!