使用实体框架中的可选记录级联删除

Posted

技术标签:

【中文标题】使用实体框架中的可选记录级联删除【英文标题】:Cascade delete with optional records in Entity Framework 【发布时间】:2016-02-25 01:06:57 【问题描述】:

我正在尝试使用 Entity Framework 开发一个 ASP.net MVC 应用程序,在过去的大约 8 小时内,我试图修复一些问题,但没有成功。我有 3 个模型,OverhourAccountingVacationOverhour 是父模型,一旦我们创建了Overhour,我们可以用它创建一个AccountingVacation 记录一次。我们不需要创建一个,所以我们可以有一个Overhour 而没有AccountingVacation。重要的是,当我们删除Overhour 时,我们应该同时删除AccountingsVacations(如果它们存在的话)。

我首先使用代码,我尝试使用 Data Annotations,但似乎你无法使用可选模型执行此操作,所以我现在使用 Fluent Api。这是我用于OverhourAccounting 之间关系的东西:

modelBuilder.Entity<Overhour>()
.HasOptional<Accounting>(s => s.Accounting)
.WithOptionalPrincipal()
.WillCascadeOnDelete(true);

即使我使用 CodeFirst,我也会使用插件来创建模型图以进行测试,并且模型看起来也不错(我猜):

Diagram(好像不能直接包含图片)

据我了解,它说“End1Delete 上的级联”。所以当我删除Overhour时,会计记录也应该被删除,但它不起作用,它只是将它设置为null。

另一件事是,我不确定哪个是父母。我的意思是,我应该有一个像这样的Overhour 模型:

class Overhour 
    ...
    public int AccountingId  get; set; 
    public virtual Accounting Accounting  get; set; 

或者是这样的:

class Overhour 
    ...
    public virtual Accounting Accounting  get; set; 

或者也许我应该将此属性包含在会计模型中?像这样:

class Accounting 
    ...
    public virtual Overhour Overhour  get; set; 

也许我需要两者都做?

我很困惑,有什么想法吗?

谢谢

【问题讨论】:

【参考方案1】:

我能够使用可选记录进行级联删除:

public class Overhour

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual Guid Id  get; set; 


public class Accounting

    [ForeignKey("Overhour")]
    public virtual Guid Id  get; set; 

    public virtual Overhour Overhour  get; set; 


public class Vacation

    [ForeignKey("Overhour")]
    public virtual Guid Id  get; set; 

    public virtual Overhour Overhour  get; set; 


protected override void OnModelCreating(DbModelBuilder modelBuilder)

    modelBuilder.Entity<Accounting>()
        .HasRequired(accounting => accounting.Overhour)
        .WithOptional()
        .WillCascadeOnDelete(true);

    modelBuilder.Entity<Vacation>()
        .HasRequired(vacation => vacation.Overhour)
        .WithOptional()
        .WillCascadeOnDelete(true);

【讨论】:

事情就是这样,会计不需要有加班记录。这也是可选的。因此,当我尝试使用您提供的代码时,我会收到类似 Cascading foreign key 'FK_dbo.Accountings_dbo.Overhours_AccountingId' cannot be created where the referencing column 'Accountings.AccountingId' is an identity column. 的错误。 根据this,如果外键字段可以为空,那么在删除主体时,依赖的外键字段将设置为空;被抚养人不会被删除。我不知道如何使外键字段不可为空和可选。 是的,我认为我想做的事情是不可能的,因为双方都是可选的。我猜我只会使用自定义代码。谢谢。

以上是关于使用实体框架中的可选记录级联删除的主要内容,如果未能解决你的问题,请参考以下文章

实体框架级联删除(继承)

实体框架级联删除 - FOREIGN KEY 约束

使用多个外键级联删除

csharp 使用外键使用实体框架和数据库第一模型进行级联删除的示例。

ssh框架复习

Postgres - 级联删除不起作用