【问题标题】:Conflict with reference constraint in TPT code-first Entity Framework与 TPT 代码优先实体框架中的引用约束冲突
【发布时间】:2018-08-15 08:34:54
【问题描述】:

我在 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”中。

在我看来,这听起来像是属于已删除 SpecialProductsProperties 没有被删除。我对数据库几乎没有经验,但据我了解,这应该使用级联删除来解决,但我似乎无法配置它。

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

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

EF6 Cascade Delete

Code First Cascade Delete

TPT Cascade Delete

【问题讨论】:

  • RemoveSomeProducts 中的 products var 是否包含属性列表?还是 MyProperties 为空?
  • @joaoruimartins 您可能正在做某事,确实是null。我尝试在我提到的第三个链接中使用AllProducts.Include(...),但这不起作用,因为并非所有Products 都有Properties。它抛出一个异常。
  • 这可能是问题所在。或者在实际上是与属性有关系的 SpecialProduct 时使用 Product 。拆分这些课程的任何理由?根据我的经验,您最终可能会遇到各种问题。仅在真正需要时在 EF 实体中使用继承。
  • 好吧,让我们这样说:拥有继承确实有意义。我可以做 TPH,但是拥有一个很大的非规范化表,将来必须扩展,这对我来说听起来不是最好的解决方案。如果可能,我宁愿保留 TPT
  • 尝试使 MyProperties 成为虚拟属性,并检查添加 .Include() 时是否仍然出现相同的错误。

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


【解决方案1】:

首先,您必须在查询中明确包含导航属性。比由于某种原因RemoveRange 不能按预期使用级联删除,但如果您逐个迭代并删除它就可以了。

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

【讨论】:

  • 您的解决方案的第一行正是我所需要的。但是我无法确认RemoveRange 不起作用。对我来说它工作得很好。
猜你喜欢
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多