引入FOREIGN KEY约束可能会导致循环或多个级联路径

cho*_*bo2 31 entity-framework cascading

我收到了这个错误

在表'Regions'上引入FOREIGN KEY约束'FK_dbo.Regions_dbo.Countries_CountryId'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.无法创建约束.查看以前的错误.

我想知道这是否意味着我的数据库设计不好?我读到你关闭了级联或类似的东西,但我不确定这是否将问题从地毯中扫除.

我只是让EF通过我的域类生成我的表(此时我没有使用任何数据注释或流畅的映射).

       public class Country
        {
            public Country()
            {
                this.Stores = new List<Store>();
                this.Regions = new List<Region>();
                Id = GuidCombGenerator.GenerateComb();
            }

            public Guid Id { get; private set; }

            private string name;

            public string Name
            {
                get { return name; }
                set
                {
                    name = value.Trim();
                }
            }

            private string code;

            public string Code
            {
                get { return code; }
                set
                {
                    code = value.Trim();
                }
            }

            public virtual ICollection<Store> Stores { get; set; }
            public virtual ICollection<Region> Regions { get; set; }
        }


          public class City
        {
            public City()
            {
                this.Stores = new List<Store>();
                Id = GuidCombGenerator.GenerateComb();
            }

            public Guid Id { get; private set; }

            private string name;

            public string Name
            {
                get { return name; }
                set
                {
                    name = value.Trim();
                }
            }


            public Guid RegionId { get; set; }
            public virtual Region Region { get; set; }

            public virtual ICollection<Store> Stores { get; set; }
        }


            public class Region
        {
            public Region()
            {
                this.Cities = new List<City>();
              this.Stores = new List<Store>();


                Id = GuidCombGenerator.GenerateComb();
            }

            public Guid Id { get; private set; }


            private string state;

            public string State
            {
                get { return state; }
                set
                {
                    state = value.Trim();
                }
            }


            public Guid CountryId { get; set; }
            public virtual ICollection<City> Cities { get; set; }
            public virtual Country Country { get; set; }
           public virtual ICollection<Store> Stores { get; set; }
        }


  public class Store
    {
        public Store()
        {
            Id = GuidCombGenerator.GenerateComb();

            Users = new List<User>();
        }

        public Guid Id { get; private set; }

        public Guid CountryId { get; set; }
        public Guid CityId { get; set; }
        public Guid RegionId { get; set; }
        public virtual City City { get; set; }
        public virtual Country Country { get; set; }
        public virtual Region Region { get; set; }

        public virtual ICollection<User> Users { get; set; }

    }
Run Code Online (Sandbox Code Playgroud)

可能是因为商店?

Sla*_*uma 54

模型中的所有关系是必需的,因为所有的外键的属性(CountryId,RegionId,CityId),都不能为空.对于所需的一对多关系,EF将按惯例启用级联删除.

Country并且Region有多个Store表的删除路径,例如,如果删除Country相关的Stores可以通过三个不同的级联路径删除(SQL Server不允许):

  • Country - > Store
  • Country- > Region- >Store
  • Country- > Region- > City- >Store

您必须通过使用Fluent API禁用级联删除或将某些关系定义为可选(使用可为空的外键Guid?)来避免此类不明确的删除路径.

或者Stores从除以外的所有实体中删除集合(以及反向引用和FK属性)City.对我来说,这些集合看起来多余,因为您可以Country通过浏览Regions.Cities.Stores集合找到所有商店.

  • +1提供信息; 唉,这对SQL Server的限制很烦人.在许多情况下,您有一个表,它实现了两个表之间的多对多关系,并且您希望将不可为空的外键放入关系表中的这两个表中,并且删除任何一个表.这些表级联到关系表.所以我想我们留下了一个非理想的解决方案,让一个外键可以为空.无论是那个还是每次都实现自定义触发器.什么是皮塔饼. (12认同)

Mor*_*eza 24

添加modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()OnModelCreating你的方法DataContext文件如下:

public class YourDataContext : DbContext
{
    public DbSet<Country> Countries{ get; set; }
    ...


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

    }
}
Run Code Online (Sandbox Code Playgroud)

同样的问题:实体框架 - 如何解决 - 外键约束 - 可能导致周期 - 或多 -

  • 这不是解决方案,而是解决问题. (19认同)
  • 当您对架构设计没有任何控制权时,这是完全正确的解决方案. (4认同)