实体框架:为什么忽略WillCascadeOnDelete()方法?

时间:2015-06-09 10:33:39

标签: c# entity-framework one-to-many cascade

以下是我的情况:

public abstract class Article
{
    [key]
    public Guid Guid { get; set;}

    public string Name { get; set;}
    .
    .
    .
}

public class Download : Article
{
    ...
}

public abstract class Category : Article
{
    ...
}

public class DownloadCategory : Category 
{
    ....
}

然后我应该在下载和DownloadCategory之间建立多对多的关系:

public class DownloadInCategory
{
    [Key, Column(Order = 1), Required]
    [ForeignKey("Download")]
    Public Guid DownloadGuid { get; set; }

    Public Download Download { get; set; }

    [Key, Column(Order = 2), Required]
    [ForeignKey("Category")]
    Public Guid CategoryGuid { get; set; }

    Public DownloadCategory Category { get; set; }
}

当我致电Add-Migration时,DownloadInCategory实体的创建迁移是:

CreateTable("dbo.DownloadInCategories",
c => new
{
    CategoryGuid = c.Guid(nullable: false),
    DownloadGuid = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid })
.ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid)
.ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true)
.Index(t => t.CategoryGuid)
.Index(t => t.DownloadGuid);

这是我的问题: 正如您所注意到的那样,它不会将cascadeDelete: true添加到其中一个外键中。 WHY !!!!!! ?????

我应该提一下,我没有更改任何modelbuilder公约。 所以这个模式应该在迁移中删除Casscade。我的属性为[Required]

我做错了什么?

谢谢你们......

更新 请注意,ArticleCategory类是abstract。 我改变了上面的课程

更新2: 此架构没有逻辑问题。如果我手动编辑迁移,它将正常更新数据库。

更新3: 我的EF继承方法是TPC

更新4: 经过一些调查和测试似乎问题是从Category继承的。 当DownloadCategoryCategory继承时,未部署Cascade。但是当我直接从文章继承DownloadCategory时,就会部署Cascade。 但又为什么呢?

1 个答案:

答案 0 :(得分:3)

我认为这是因为:

DownloadCategory : Category : Article

VS

Download : Article

关键是在Article类上。多个DownloadCategories可以使用相同的Category,因此它不会在删除时级联,因为这可能会导致其他DownloadCategory损坏。

这可能是Entity Framework的失败,因为您使用的是TPC,因此应该推断出这一点。请查看this article了解变通方法。

特别是这些部分:

  

在大多数情况下,实体框架可以推断出哪种类型   依赖,哪个是关系中的主体。但是,什么时候   关系的两端都是必需的,或者双方都是可选的   实体框架无法识别依赖关系和主体。什么时候   关系的两端都是必需的,使用WithRequiredPrincipal   或WithRequiredDependent方法之后的HasRequired。两端都结束了   关系是可选的,使用WithOptionalPrincipal或   WithOptionalDependent方法之后的HasOptional

// Configure the primary key for the OfficeAssignment 
modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 

modelBuilder.Entity<Instructor>() 
    .HasRequired(t => t.OfficeAssignment) 
    .WithRequiredPrincipal(t => t.Instructor);
  

您可以使用以下命令在关系上配置级联删除   WillCascadeOnDelete方法。如果是依赖实体的外键   不可为空,然后Code First设置级联删除   关系。如果依赖实体上的外键可以为空,   Code First不会在关系上设置级联删除,以及何时   删除主体后,外键将设置为null

     

您可以使用以下命令删除这些级联删除约定:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
  

以下代码将配置所需的关系   禁用级联删除。

modelBuilder.Entity<Course>() 
    .HasRequired(t => t.Department) 
    .WithMany(t => t.Courses) 
    .HasForeignKey(d => d.DepartmentID) 
    .WillCascadeOnDelete(false);