Введение ограничения FOREIGN KEY может привести к циклам или нескольким каскадным путям

Я получаю эту ошибку

Представление ограничения FOREIGN KEY "FK_dbo.Regions_dbo.Countries_CountryId" в таблице "Регионы" может вызвать циклов или нескольких каскадных путей. Укажите ВКЛ. УДАЛИТЬ НЕТ ДЕЙСТВИЯ или ВКЛ. ОБНОВЛЯЙТЕ НЕТ ДЕЙСТВИЙ или измените другие ограничения 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; }

    }

Может ли это быть из-за магазинов?

Ответ 1

Все отношения в вашей модели требуются, потому что все свойства внешнего ключа (CountryId, RegionId, CityId) не имеют значения NULL. Для требуемых отношений "один ко многим" EF разрешает каскадное удаление по соглашению.

Country и Region имеют несколько путей удаления в таблице Store, например, если вы удаляете Country связанный Store можно удалить с помощью трех разных каскадных путей (которые не разрешены с помощью SQL Server):

  • CountryStore
  • CountryRegionStore
  • CountryRegionCityStore

Вы должны избегать таких неоднозначных путей удаления путем отключения каскадного удаления с использованием Fluent API или путем определения некоторых отношений как необязательных (с нулевым внешним ключом Guid?).

Или удалите коллекции Stores (и обратные ссылки и свойства FK) из всех объектов, кроме City. Для меня эти коллекции выглядят излишними, потому что вы можете найти все магазины в Country, перейдя по коллекциям Regions.Cities.Stores.

Ответ 2

Добавьте 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>();

    }
}

Тот же вопрос: entity-framework-how-to-solve-foreign-key-constraint-may-cause-cycles-or-multi