8

我正在尝试使用 Entity Framework Code First Fluent API 映射现有数据库。我在多对多关系和级联删除的情况下苦苦挣扎。

这是我的两个 POCO 课程:

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

目前,我只有一个导航属性 from Footo Bar。那是因为在我的真实场景中,任何人从BarFoo. 从Footo的关系Bar实际上是 0,n 这意味着一个实例Foo不需要 的实例Bar

我现有的数据库在这两个表之间有一个连接表。该表如下所示:

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

因为我不想在我的项目中创建这样的 POCO 类,所以我像这样映射表:

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

这非常适合插入。在 Foo 上插入实体,然后在现有Foo_Bar表上插入。

但是当我删除 a 时Foo,我想删除连接表上的记录,而不是子表上的记录。这意味着我想删除记录Foo_Bar但不将此级联扩展到Bar.

这样的映射可能吗?我应该提到,在我的上下文中我删除了这两个OneToManyCascadeDeleteConventionManyToManyCascadeDeleteConvention因为 99% 的时间我不会使用级联删除。这是一种具体情况。

通过跟踪 Entity Framework 生成的 SQL,我还注意到,如果我检索一个Foo实例并将其中的所有 Bars 设置为 EntityState.Deleted,EF 将删除Foo_Bar和中的两个记录Bar。我应该提到的最后一件事是我正在一个断开连接的场景中工作。

我试图搜索这个,但似乎我没有使用正确的关键字,因为在这种情况下我找不到任何人。在这一点上,我看到的唯一解决方案是Map上课FooBar,但我希望有办法做到这一点。

- 编辑

看来我的删除方法一开始是错误的。当我尝试删除时,我没有通过填充Foo列表的实例。在该更改之后,实体框架为列表Bar中的每个创建一个删除语句。Bar我仍然遇到更新问题,例如同时添加和删除项目。将进行更多测试并在此处发布。

提前致谢。

4

1 回答 1

7

但是当我删除一个 Foo 时,我想删除连接表上的记录,而不是子表上的记录。这意味着我想删除 Foo_Bar 上的记录,但不想将此级联扩展到 Bar。

这样的映射可能吗?

这实际上是唯一可能的映射。您不能将级联删除扩展到Bar表,因为在关系中(从数据库模式的角度来看)Foo_Bar连接表是关系中的依赖表并且Bar主体。通常,级联删除仅在删除主体时有效,但在删除依赖项时无效。

因此,您不必担心Bar在删除 a 时可能会删除 aFoo并且您不必为此应用任何特殊设置。

但是,当您删除ManyToManyCascadeDeleteConvention. 它对整个模型全局起作用,并且没有选项可以为特定的多对多关系再次打开级联删除。(没有WillCascadeOnDelete(true)像一对多或一对一关系那样的多对多关系。)

您确定ManyToManyCascadeDeleteConvention在您的模型中确实需要删除吗?我从来没有遇到过这样的模型,当删除一个连接实体(或)时,删除连接表中的相关条目是有意义的。FooBar

于 2012-11-21T20:11:33.463 回答