db,EF中的DELETE语句冲突REFERENCE约束

时间:2019-03-25 21:20:56

标签: c# sql entity-framework

第一个问题:尝试更新数据库时发生问题:

  

DELETE语句冲突REFERENCE约束“ FK_Products_ProductTypes_ProductTypeId”。在数据库“ GdmStore”的表“ dbo.Products”的列“ ProductTypeId”中发生冲突。

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

我的DataContext:

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; }
}

1 个答案:

答案 0 :(得分:1)

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

例如,查看下表:

--------------------------------------
         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,它将失败。为什么?好吧,如果我删除该产品类型,那么我的Electric Pizza Cutter产品将具有神秘的产品类型(不再有 1000)。它是孤儿。数据库与Daddy Warbucks不一样,它们讨厌孤儿。

如果确实需要删除某些内容,则需要从链的底部一直拆卸到顶部。但是您会发现,很少有 ever 在数据库中被删除。而不是删除,您应该将其标记为无效。我的首选路线是使用结束日期。

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

就像这样,我的产品类型不再使用,但是数据库中的旧内容仍然可以在需要时引用它们。