代码之家  ›  专栏  ›  技术社区  ›  Stian

FK约束可能导致循环或多个级联路径

  •  2
  • Stian  · 技术社区  · 6 年前

    为什么我的初始数据库 update database failing,我需要在我的数据库表类中更改什么才能使它工作?

    当然,我可以将迁移脚本中的 ondelete:referentialaction.cascade 更改为 ondelete:referentialaction.noaction ,但随后我将在应用程序中面临其他问题。我正在寻找一个解决方案,在这个解决方案中,不需要编辑由 add migration生成的迁移脚本。换句话说,我愿意更改我的数据库模式。

    我想要的行为是,当我删除一个 product 时,关联的 productpropertyoptionforproducts 也会被删除,但不会被删除,而不是与 productpropertyoptionforproducts 关联的 productpropertyoptionforproducts .。

    这是迁移输出错误消息:.

    在表“propertyoptionsforproducts”上引入外键约束“fk”propertyoptionsforproducts“u productpropertyoptionsid”可能会导致循环或多个级联路径。指定“不删除任何操作”或“不更新任何操作”,或修改其他外键约束。 无法创建约束或索引。请参阅前面的错误。

    生成的导致错误的SQL命令:

    create table[propertyoptionsforproducts](
    [id]int非空标识,
    [CustomNumberValue]十进制(18,2)不为空,
    [CustomRangeFrom]十进制(18,2)不为空,
    [CustomRangeTo]十进制(18,2)不为空,
    [自定义字符串值]nvarchar(max)空,
    [ProductID]int不为空,
    [ProductPropertyID]int不为空,
    [ProductPropertyOptionId]int不为空,
    约束[pk_propertyoptionsforproducts]主键([id]),
    约束[FK产品的属性选项\U产品ID]
    外键([ProductID])
    删除层叠时引用[产品]([ID]),
    约束[FK撘propertyoptionsforforproducts撘productpropertyoptions撘productpropertyoptionid]
    外键([ProductPropertyOptionId])
    删除层叠时引用[ProductPropertyOptions]([ID])。
    )(二)
    

    课程:

    public class productpropertyoption
    {
    public int id_get;set;
    public int productpropertyid_get;set;
    //更多属性
    public productproperty属性get;set;
    public ICollection<propertyoptionforproduct>propertyoptionforproducts get;set;
    }
    
    
    产品的公共类属性选项
    {
    public int id_get;set;
    public int productid_get;set;
    public int productpropertyid_get;set;
    public int productpropertyoptionid get;set;
    //更多属性
    公共产品获取;设置;
    public productpropertyoption productpropertyoption_get;set;
    }
    
    
    公共类产品
    {
    public int id_get;set;
    公开bool published_get;set;
    public int productgroupid_get;set;
    public int productGroupSortOrder获取;设置;
    //更多属性
    public int producttypeid_get;set;
    
    公共ICollection<productImage>图像获取;设置;
    public ICollection<propertyoptionforproduct>productpropertyoptionforproducts get;set;
    公共ICollection<IdentifierForProduct>IdentifierForProducts get;set;
    公共产品类型get;set;
    公共ICollection<frontpageproduct>infrontpages get;set;
    公共ICollection<productincategory>incategories get;set;
    }
    
    
    公共类产品类型
    {
    public int id_get;set;
    公共字符串标题get;set;
    公共列表<productIdentifierInType>标识符get;set;
    公共列表<productproperty>属性get;set;
    公共ICollection<product>产品获取;设置;
    }
    
    
    公共类产品属性
    {
    public int id_get;set;
    public int producttypeid_get;set;
    //更多属性
    公共列表<productpropertyoption>选项获取;设置;
    公共产品类型producttype get;set;
    }
    
    
    

    数据库(产品和类别部分)说明:

    .onDelete: ReferentialAction.Cascade在迁移脚本中onDelete: ReferentialAction.NoAction但是在我的申请中我会面临其他的问题。我正在寻找一个不需要编辑由add-migration.换句话说,我可以对数据库模式进行更改。

    我想要的行为是当我删除Product,关联的ProductPropertyOptionForProducts也会被删除,但不会被删除。ProductPropertyOption它与产品属性产品选项.

    这是迁移输出错误消息:

    在表“propertyoptionsforproducts”上引入外键约束“fk”propertyoptionsforproducts“u productpropertyoptionsid”可能会导致循环或多个级联路径。指定“不删除任何操作”或“不更新任何操作”,或修改其他外键约束。 无法创建约束或索引。请参阅前面的错误。

    生成的导致错误的SQL命令:

    CREATE TABLE[PropertyOptionsForProducts] (
    [Id] int NOT NULL IDENTITY,
    [CustomNumberValue] decimal (18, 2) NOT NULL,
    [CustomRangeFrom] decimal (18, 2) NOT NULL,
    [CustomRangeTo] decimal (18, 2) NOT NULL,
    [CustomStringValue] nvarchar(max) NULL,
    [ProductId] int NOT NULL,
    [ProductPropertyId] int NOT NULL,
    [ProductPropertyOptionId] int NOT NULL,
    CONSTRAINT[PK_PropertyOptionsForProducts] PRIMARY KEY([Id]),
    CONSTRAINT[FK_PropertyOptionsForProducts_Products_ProductId]
        FOREIGN KEY([ProductId])
        REFERENCES[Products] ([Id]) ON DELETE CASCADE,
    CONSTRAINT[FK_PropertyOptionsForProducts_ProductPropertyOptions_ProductPropertyOptionId]
        FOREIGN KEY([ProductPropertyOptionId])
        REFERENCES[ProductPropertyOptions] ([Id]) ON DELETE CASCADE
    );
    

    课程:

    public class ProductPropertyOption
    {
        public int Id { get; set; }
        public int ProductPropertyId { get; set; }
        // some more properties
        public ProductProperty Property { get; set; }
        public ICollection<PropertyOptionForProduct> PropertyOptionForProducts { get; set; }
    }
    
    
    public class PropertyOptionForProduct
    {
        public int Id { get; set; }
        public int ProductId { get; set; }
        public int ProductPropertyId { get; set; }
        public int ProductPropertyOptionId { get; set; }
        // some more properties
        public Product Product { get; set; }
        public ProductPropertyOption ProductPropertyOption { get; set; }
    }
    
    
    public class Product
    {
        public int Id { get; set; }
        public bool Published { get; set; }
        public int ProductGroupId { get; set; }
        public int ProductGroupSortOrder { get; set; }
        // some more properties
        public int ProductTypeId { get; set; }
    
        public ICollection<ProductImage> Images { get; set; }
        public ICollection<PropertyOptionForProduct> ProductPropertyOptionForProducts { get; set; }
        public ICollection<IdentifierForProduct> IdentifierForProducts { get; set; }
        public ProductType Type { get; set; }
        public ICollection<FrontPageProduct> InFrontPages { get; set; }
        public ICollection<ProductInCategory> InCategories { get; set; }
    }
    
    
    public class ProductType
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public List<ProductIdentifierInType> Identifiers { get; set; }
        public List<ProductProperty> Properties { get; set; }
        public ICollection<Product> Products { get; set; }
    }
    
    
    public class ProductProperty
    {
        public int Id { get; set; }
        public int ProductTypeId { get; set; }
        // some more properties
        public List<ProductPropertyOption> Options { get; set; }
        public ProductType ProductType { get; set; }
    }
    

    数据库(产品和类别部分)说明:

    2 回复  |  直到 6 年前
        1
  •  2
  •   Ivan Stoev    6 年前

    ProductType PropertyOptionForProduct

    Product

    ProductProperty ProductPropertyOption

    modelBuilder.Entity<ProductType>()
        .HasMany(e => e.Properties)
        .WithOne(e => e.ProductType)
        .OnDelete(DeleteBehavior.Restrict);
    

    db.Remove(db.Set<ProductType>().Single(e => e.Id == id));
    db.SaveChanges();
    

    Properties

    var productType = db.Set<ProductType>().Include(e => e.Properties).Single(e => e.Id == id);
    db.RemoveRange(productType.Properties);
    db.Remove(productType);
    db.SaveChanges();
    
        2
  •  2
  •   TommCatt Tony Andrews    6 年前

    select * from ProductTypeForDelete where ID = 1001;
    ID    TABLE              KEY
    ===== ==========         =====
    1001  Product            300
    1001  Product            301
    1001  ProductProperty    203
    

    delete from ProductTypeForDelete where ID = 1001;
    

    delete

    delete from ProductForDelete where ID = 300;