web-dev-qa-db-ja.com

FOREIGN KEY制約を導入すると、サイクルまたは複数のカスケードパスが発生する場合があります

このエラーが発生しています

テーブル 'Regions'にFOREIGN KEY制約 'FK_dbo.Regions_dbo.Countries_CountryId'を導入すると、サイクルまたは複数のカスケードパスが発生する場合があります。 ON DELETE NO ACTIONまたはON UPDATE NO ACTIONを指定するか、他の外部キー制約を変更します。制約を作成できませんでした。以前のエラーを参照してください。

これは私のデータベース設計が悪いことを意味しているのだろうか?カスケードやそのようなものをオフにすることを読んでいますが、それが問題を敷き詰めているのかどうかはわかりません。

ドメインクラスを介してEFにテーブルを生成させるだけです(この時点では、データアノテーションや流fluentなマッピングは使用していません)。

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

    }

店舗のせいでしょうか?

31
chobo2

モデル内のすべての関係は必須すべての外部キープロパティ(CountryIdRegionIdCityId)はnull不可であるため=。必要な1対多の関係の場合、EFは慣例によりカスケード削除を有効にします。

CountryRegionには、Storeテーブルへの複数の削除パスがあります。たとえば、Countryを削除する場合、関連するStoresを削除できます3つの異なるカスケードパス経由(SQL Serverでは許可されません):

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

Fluent APIを使用してカスケード削除を無効にするか、一部の関係をoptional(nullable外部キーGuid?)。

または、Storesを除くすべてのエンティティからCityコレクション(および逆参照とFKプロパティ)を削除します。私にとっては、Country内のすべてのストアを見つけることができるため、これらのコレクションは冗長に見えます。Regions.Cities.Storesコレクション。

54
Slauma

次のようにOnModelCreatingファイルのDataContextメソッドにmodelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()を追加します。

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

24
Morteza