0

質問:ON DELETE CASCADEオプションをベーステーブルの流暢なAPIを使用して外部キー制約に指定するにはどうすればよいですか?私は他のテーブルとの関係でそれを行う方法を知っていますが、どのようにTPT(Table Per Type)テーブルのためにこれを生成させるのですか?流暢なAPIを使ってベーステーブルのカスケード削除をどのように指定しますか?

説明: 私は外部キーの関係を指しているわけではありません。私のDbContextでは、エンティティのマッピングオブジェクトを常に使用しています。なぜなら、ほとんどの場合、慣習的なアプローチを受け入れるのとは対照的に明示的であることが望ましいからです。つまり、TPTテーブルのすべての設定は、EntityTypeConfiguration<SomeEntityClass>クラスで処理されています。

別のクラスから派生した新しいクラスを作成してTPT関係を定義すると、ON DELETE CASCADEは問題であるSQL制約に生成されません。

は、上記のコードは本当に簡単です

public class Person 
    { 
     public int PersonId { get; set; } 
     public string Name { get; set; } 
    } 

    public class OtherPerson : Person 
    { 
     public string SomeOtherProperty { get; set; } 
    } 

    public class PersonMap : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Person> 
    { 
     public PersonMap() 
     { 
      this.HasKey(t => t.PersonId); // Primary Key 

      this.Property(t => t.PersonId) 
       .HasColumnName("PersonId") // Explicitly set column name 
       .IsRequired() // Field is required/NOT NULL 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // Specify as Identity (Not necessary, but I'm explicit) 

      this.Property(t => t.Name) 
       .HasColumnName("Name") // Explicitly set column name 
       .IsRequired() // Field is required/NOT NULL 
       .HasMaxLength(50); // Max Length 

      this.ToTable("People"); // Map to table name People 
     } 
    } 

public class OtherPersonMap : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<OtherPerson> 
{ 
    public OtherPersonMap() 
    { 
     this.Property(t => t.SomeOtherProperty) 
      .HasColumnName("SomeOtherProperty") // Explicitly set column name 
      .IsRequired() // Field is required/NOT NULL 
      .HasMaxLength(10); // Max Length 

     this.ToTable("OtherPeople"); /* Map to table name OtherPeople 
             * This also causes TPT to create a shared primary key from the base table 
             * and double serving as a foreign key to base table. 
             */ 
    } 

...次のコードを見てください。私は2つのタイプがあり、それらは正しくデータベースに作成されます。新しいOtherPersonを作成してデータベースに保存すると、最初にPeopleテーブルのレコードとOtherPeopleテーブルのレコードが2つのレコードを作成します。これは、OtherPeopleからPeopleへの外部キーでもある共有プライマリキーです。 DbContextまたはEFでは、コード内のOtherPersonを削除すると、どちらのレコードも正しく削除されます。ただし、データベースからレコードを直接削除すると、孤立したレコードがPeopleテーブルに残されます。

したがって、流暢なAPIを使用してベーステーブルに対して生成された外部キー制約に、ON DELETE CASCADEを指定するにはどうすればよいですか?

申し訳ありません申し訳ありませんが、長すぎますが、私は自分の問題ができる最高のものを記述したかっただけです。 ありがとうございます。

答えて

0

DbContextまたはEFでは、コード内のOtherPersonをI で削除すると、正しく両方のレコードが正しく削除されます。ただし、 レコードをデータベースから直接削除すると、孤児レコードが Peopleテーブルに残されます。

あなたはOtherPeopleテーブル(派生エンティティ)からレコードを削除したいと言っているように見えると削除カスケードPeople表(基本エンティティ)内の対応するレコードが同様に削除されることを確保すべきです。

これは間違った方向です。 EFは、基本エンティティテーブルから派生エンティティテーブルに移動する関係および外部キー制約を作成します。PKテーブルはPeopleで、FKテーブルはOtherPeopleです。この関係をカスケード削除すると、対応するPeopleレコードが削除されるときに、OtherPeopleレコードが削除されることを保証することしかできません。

この関係だけでも、カスケード削除なしでも、OtherPeopleテーブルの孤立レコードは、FK制約に違反するため、孤立したレコードを取得できません。 (関連するOtherPersonのないPersonは削除できません。)

実際には、PKテーブルがOtherPeopleで、FKテーブルがPeopleであるデータベースに2番目のFK制約が必要です。この関係はEF TPTマッピングによって全く作成されず、People上のPKが(少なくともSQL Serverでは)IDでない場合にのみ機能します。しかしそれはあなたのモデルのアイデンティティです。したがって、EFではもちろん、データベース内のカスケード削除でこの関係を作成することすらできません。

EFが実際にデータベースに作成する関係(これはカスケード削除では必要ありません)に戻って、私はEFコード・ファーストにマッピングオプションがあるとは思いません。 TPTマッピングに必要な関係。唯一の方法は、データベースで直接行うか、Code-Firstモデルからデータベースを生成したい場合は、カスケード削除を設定する未処理のSQL文をカスタムイニシャライザに書き込み、データベースに送信しますすべての表と関係が作成された後

どういうわけか、データベースにPeopleOrderのようなもので、OtherPeopleOrderItemのようなものです - だけではなく、1-to-*1-to-0..1関係。あなたが望むのは、子OrderItemが削除された場合、親がOrderを削除するということです。これは、従属者がプリンシパルを削除することを意味します。

+0

お返事ありがとうございます。私は本当にapiを通じてそれを設定する方法があることを望んでいた。データベースに手動で作成すると思います。再度、感謝します。 –

関連する問題