简体   繁体   English

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

[英]Entity Framework : Why WillCascadeOnDelete() Method is ignored?

Here is my situation : 这是我的情况:

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 
{
    ....
}

And then I should have a many-to-many relation between Download and DownloadCategory like this : 然后我应该在Download和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; }
}

When I call Add-Migration the created migration for DownloadInCategory entity is : 当我调用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);

Here is My Question : As you notice it's not adding cascadeDelete: true to one of foreign keys. 这是我的问题:你注意到它没有将cascadeDelete: true添加到其中一个外键。 WHY!!!!!!????? 为什么!!!!!!?????

I should mention that I didn't change any of modelbuilder Conventions. 我应该提一下,我没有更改任何modelbuilder约定。 So this schema should add Casscade on delete in migration. 所以这个模式应该在迁移中删除Casscade。 My properties are [Required] . 我的属性是[Required]

What am I doing wrong? 我究竟做错了什么?

Thanks guys... 多谢你们...

Update : Please notice that Article and Category classes are abstract . 更新:请注意ArticleCategory类是abstract I changed classes above 我改变了上面的课程

Update 2: There is no Logical issue with this schema. 更新2:此架构没有逻辑问题。 If I edit the migration manually, It will update the database normally. 如果我手动编辑迁移,它将正常更新数据库。

Update 3: My EF Inheritance Methodology is TPC 更新3:我的EF继承方法是TPC

Update 4: After Some investigation and tests It seems problem is inheritanced from Category . 更新4:经过一些调查和测试似乎问题是从Category继承。 When DownloadCategory is Inherited from Category , Cascade is not deployed. DownloadCategoryCategory继承时,不会部署Cascade。 but when I Inherit DownloadCategory directly from Article, Cascade is deployed. 但是当我直接从文章继承DownloadCategory时,会部署Cascade。 But Why again? 但为什么又一次?

I would think this is because: 我认为这是因为:

DownloadCategory : Category : Article

vs VS

Download : Article

The key is on the Article class. 关键是在Article类上。 Multiple DownloadCategories could use the same Category , so it will not cascade on delete as this could leave other DownloadCategory 's corrupted. 多个DownloadCategories可以使用相同的Category ,因此它不会在删除时级联,因为这可能会使其他DownloadCategory损坏。

This is possibly a failing of Entity Framework, since you are using TPC, this should be inferred. 这可能是实体框架的失败,因为您正在使用TPC,这应该是推断的。 Take a look at this article for workarounds. 看看这篇文章的解决方法。

Specifically these sections: 特别是这些部分:

In most cases the Entity Framework can infer which type is the dependent and which is the principal in a relationship. 在大多数情况下,实体框架可以推断哪种类型是依赖关系,哪种类型是关系中的主体。 However, when both ends of the relationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. 但是,当关系的两端都是必需的或双方都是可选的时,实体框架无法识别依赖关系和主体。 When both ends of the relationship are required, use WithRequiredPrincipal or WithRequiredDependent after the HasRequired method. 当需要关系的两端时,在HasRequired方法之后使用WithRequiredPrincipalWithRequiredDependent When both ends of the relationship are optional, use WithOptionalPrincipal or WithOptionalDependent after the HasOptional method. 当关系的两端都是可选的时, WithOptionalDependentHasOptional方法之后使用WithOptionalPrincipalWithOptionalDependent

// 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);

You can configure cascade delete on a relationship by using the WillCascadeOnDelete method. 您可以使用WillCascadeOnDelete方法在关系上配置级联删除。 If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. 如果依赖实体上的外键不可为空,则Code First会在关系上设置级联删除。 If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null . 如果依赖实体上的外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null

You can remove these cascade delete conventions by using: 您可以使用以下命令删除这些级联删除约定:

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

The following code configures the relationship to be required and then disables cascade delete. 以下代码配置所需的关系,然后禁用级联删除。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM