为所有实体设置级联删除

时间:2018-06-06 17:57:10

标签: c# entity-framework-core

我正在尝试为所有实体配置DeleteBehavior。最终结果是我可以简单地运行:

DELETE FROM Companies Where Id = '1'

我的所有800个表格将在级联上清理(所有表格参考 CompanyId为FK )...

我的课程

public interface ITest
{
    string PropX { get; set; }
    Company Company { get; set; }
}

public abstract class Reg {
    public int Id { get; set; }
    public Company Company { get; set; }
}

public class Company {
    public int Id { get; set; }
    public string Name { get; set; }
}


public class Test : Reg, ITest
{
    public string Prop1 { get; set; }
    public string PropABC { get; set; }
    public string PropX { get; set; } = "My Info";
}

public class Test2 : Reg, ITest
{
    public string PropEFG { get; set; }
    public string PropX { get; set; } = "My Info2";
}

public class Test3 : Reg, ITest
{
    public string PropExample { get; set; }
    public string PropX { get; set; } = "My Info3";
}

如果我这样做,那就完美了:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Test>().HasOne(p=>p.Company).WithMany().OnDelete(DeleteBehavior.Cascade);
    modelBuilder.Entity<Test2>().HasOne(p=>p.Company).WithMany().OnDelete(DeleteBehavior.Cascade);
    //....... not for 800 classes

 }

但我有800个课程...所以我正在尝试这样做:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    var my800Entities = modelBuilder.Model.GetEntityTypes().ToList();

    foreach (var entity in my800Entities)
    {
       modelBuilder.Entity(entity.Name).HasOne("Company").WithMany().OnDelete(DeleteBehavior.Cascade);
       /* It seems to me that this code is creating an
       extra column and not defining the already existing property */
    }

}

上面的代码生成了迁移,每个classe中还有一列,例如:

  • 其他属性......
  • 公司(使用FK限制删除行为)
  • 公司1 (使用FK 级联删除行为)

我需要做什么,只有1列(公司)有Cascade删除行为?

1 个答案:

答案 0 :(得分:1)

首先,过滤实现该接口的实体类型:

var my800Entities = modelBuilder.Model.GetEntityTypes()
    .Where(t => typeof(ITest).IsAssignableFrom(t.ClrType))
    .ToList();

然后(这是您的代码的主要问题),将相关类型和导航属性名称传递给HasOne方法(目前您只传递相关的类型名称,这相当于无参数通用HasOne并指示关系没有导航属性,因此EF Core将与该属性的另一个关联关联起来:

foreach (var entity in my800Entities)
{
    modelBuilder.Entity(entity.Name)
       .HasOne(typeof(Company), "Company") // <--
       .WithMany()
       .OnDelete(DeleteBehavior.Cascade);
}