与TPT代码优先实体框架中的引用约束冲突

时间:2018-08-15 08:34:54

标签: c# .net entity-framework entity-framework-6

我在Entity Framework 6中使用TPT代码优先,并具有以下设置:

public abstract class Product
{
    [Key]
    public string ProductID { get; set; }
    // a bunch of trivial properties like dates and floats
}

[Table("SpecialProducts")]
public class SpecialProduct : Product
{
    // more trivial properties
    public List<Property> MyProperties { get; set; }
}

public class Property
{
    [Key]
    public int ID { get; set; }
    [Required]
    public SpecialProduct Product { get; set; }
    // property data
}

public class MyDbContext : DbContext
{
    public DbSet<Product> AllProducts { get; set; }

    public MyDbContext()
        : base("MyDataBase")
    {}

    public RemoveSomeProducts()
    {
        var products = from product in AllProducts where /* some condition */ select product;
        AllProducts.RemoveRange(products);
        SaveChanges();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // I know I don't need both statements, and my guess is I need the first, but at this point I don't know anything anymore
        modelBuilder.Entity<Property>()
            .HasRequired(property => property.Product)
            .WithMany(product => product.MyProperties)
            .WillCascadeOnDelete(true);

        modelBuilder.Entity<SpecialProduct>()
            .HasMany(product => product.MyProperties)
            .WithRequired(property => property.Product)
            .WillCascadeOnDelete(true);
    }

}

呼叫RemoveSomeProducts()时出现以下异常:

  

SqlException:DELETE语句与REFERENCE约束“ FK_dbo.Properties_dbo.SpecialProducts_Product_ProductID”冲突。在数据库“ MyDataBase”的表“ dbo.Properties”的“ Product_ProductID”列中发生了冲突。

对我来说,这似乎是属于删除的Properties的{​​{1}}未被删除。我对数据库的经验很少,但是据我了解,应该使用级联删除来解决此问题,但是我似乎无法配置它。

所以我的问题显然是:我该如何解决?

可能的重复项似乎对我没有帮助,但可能对其他人有用:

EF6 Cascade Delete

Code First Cascade Delete

TPT Cascade Delete

1 个答案:

答案 0 :(得分:1)

首先,您必须在查询中明确包含导航属性。出于某种原因,RemoveRange不能与级联删除一起使用,但是,如果您一个接一个地迭代并删除它,那么它将起作用。

var products = Set<SpecialProduct>().Include(p => p.MyProperties).ToList();
products.ForEach(p => AllProducts.Remove(p));
SaveChanges();