删除语句冲突 db, EF 中的引用约束



第一个问题:我在尝试更新数据库时遇到问题:

删除语句冲突引用约束"FK_Products_ProductTypes_ProductTypeId"。数据库"GdmStore",表"dbo"中发生冲突。产品",列"产品类型 ID"。

第二个问题:我的对象模型是否良好,实体之间的关系是否良好? 我必须创建一个数据库,其中我有许多不同的"产品",每个"产品"都有自己的一组"参数"。

我的数据上下文:

public DataContext(DbContextOptions<DataContext> opts) : base(opts) { }
public DbSet<Product> Products { get; set; }
public DbSet<ProductType> ProductTypes { get; set; }
public DbSet<Parameter> Parameters { get; set; }
public DbSet<ProductParameter> ProductParameters { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity<Product>()
           .HasOne(c => c.ProductType)
           .WithMany(e => e.Products)
           .HasForeignKey(c => c.ProductTypeId)
           .OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<Parameter>()
           .HasOne(Pr => Pr.ProductType)
           .WithMany(Pt => Pt.Parameters)
           .HasForeignKey(Pr => Pr.ProductTypeId)
           .OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<ProductParameter>()
            .HasOne<Product>(bc => bc.Product)
            .WithMany(b => b.ProductParameters)
            .OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<ProductParameter>()
            .HasOne<Parameter>(bc => bc.Parameter)
            .WithMany(c => c.ProductParameters)
            .OnDelete(DeleteBehavior.Restrict);
}

这些是我的模型类:

public class Product //: BaseObject
{
    public int ProductId { get; set; }
    public string Number { get; set; }
    public double Amount { get; set; }
    public double PrimeCost { get; set; }
    [ForeignKey("ProductTypeId")]
    public int  ProductTypeId {  get; set; }
    public ProductType ProductType { get; set; }
    public int ProductParameterId { get; set; }
    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductType 
{   
    public int ProductTypeId { get; set; }
    public string TypeName { get; set; }
    public ICollection<Product> Products { get; set; }
    public ICollection<Parameter> Parameters { get; set; }
    public ICollection<Parameter> Parameter { get; set; } = new List<Parameter>();
    public ICollection<Product> Product { get; set; } = new List<Product>();
}
public class Parameter
{
    public int ParameterId { get; set; }
    public string Name { get; set; }
    [ForeignKey("ProductTypeId")]
    public int ProductTypeId { get; set; }
    public ProductType ProductType { get; set; }
    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductParameter 
{
    public int ProductParameterId { get; set; }
    public int ProductId { get; set; }
    public int ParameterId { get; set; }
    public Parameter Parameter { get; set; }
    public Product Product { get; set; }
    public string Value { get; set; }
}

根据错误消息,您似乎正在尝试删除另一行所依赖的行。

例如,查看下表:

--------------------------------------
         PRODUCT_TYPE
--------------------------------------
(PK)PRODUCT_TYPE_ID  |  TYPE
--------------------------------------
1000                 | Gimmick
1001                 | Life Changing

--------------------------------------------------------
                     PRODUCT
--------------------------------------------------------
(PK)PRODUCT_ID | (FK)PRD_TYPE_ID  | Name
--------------------------------------------------------
6521           | 1000             | Electric Pizza Cutter
6522           | 1001             | Bidet

如果我尝试运行DELETE FROM PRODUCT_TYPE WHERE PRODUCT_TYPE_ID = 1000它会失败。 为什么? 好吧,如果我删除该产品类型,那么我的电动披萨切割机产品将具有神秘的产品类型(不再 1000 个(。 它是孤儿。 数据库不像爸爸沃巴克 - 他们讨厌孤儿。

如果你真的要删除一些东西,你需要从链条的底部一直到顶部拆卸它。 但是你会发现,数据库中很少应该删除任何内容。 您应该将其标记为非活动状态,而不是删除。我的首选路线是使用结束日期。

--------------------------------------------------
         PRODUCT_TYPE
--------------------------------------------------
(PK)PRODUCT_TYPE_ID  |  TYPE          |  END_DATE
--------------------------------------------------
       1000          | Gimmick        | 3-25-2019
       1001          | Life Changing  | null

就这样,我的产品类型不再使用,但如果需要,数据库中的旧东西仍然可以引用它们。

最新更新