【问题标题】:How to cascade delete only on join table using Entity Framework Code First Fluent API如何使用 Entity Framework Code First Fluent API 仅在连接表上级联删除
【发布时间】:2012-11-21 19:26:09
【问题描述】:

我正在尝试使用 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;
}

目前,我只有一个从FooBar 的导航属性。那是因为在我的真实场景中,任何人从Bar 转到Foo 都是没有意义的。从FooBar 的关系实际上是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 表上插入。

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

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

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

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

--编辑

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

提前致谢。

【问题讨论】:

    标签: c# .net entity-framework ef-code-first


    【解决方案1】:

    但是当我删除一个 Foo 时,我想删除 加入表但不在子表上。意思是我要删除 Foo_Bar 上的记录,但不将此级联扩展到 Bar。

    这样的映射可能吗?

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

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

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

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

    【讨论】:

    • 我同意你的看法。这是唯一可能的映射。我不记得为什么我在写它时指定了这一点。至于删除约定的需要,嗯,我有一个场景,多对多关系的一端是一个表,其中记录与业务逻辑相关联。用户无法编辑其记录。即使有人试图错误地删除记录,也不会在该端创建级联删除,不会破坏任何内容。但我想这确实是个例外。现在我将启用约定并以其他方式处理异常。谢谢。
    猜你喜欢
    • 2014-09-26
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2014-04-19
    • 1970-01-01
    相关资源
    最近更新 更多