Entity Framework 7:関係の特定

c# ef-fluent-api entity-framework entity-framework-core

質問

以前のバージョンのEFでは、次のコードを使用して識別関係を実装できます。

public class Child
{
    [Key, Column(Order = 1)]
    public virtual int Id { get; set; }

    [Key, Column(Order = 2)]
    public virtual int ParentId { get; set; }
    public virtual Parent Parent { get; set; }
}

次のようにコレクションから子を簡単に削除する必要があります。

var parent = _context.Parents.First();
var child = parent.Children.First();

parent.Children.Remove(child);

_context.SaveChanges();

このアプローチはhttp://www.kianryan.co.uk/2013/03/orphaned-child/ (方法#2)に記載されています

しかし、EF7では、マイグレーションの作成時にこのコードが例外をスローします。

解決操作を実行中に例外がスローされました。詳細については、InnerExceptionを参照してください。 --->エンティティタイプ 'Child'には、データアノテーションで定義された複合プライマリキーがあります。複合主キーを設定するには、Fluent APIを使用します。

また、次のコードで最初ネストされた関係の特定Entity Frameworkコードを定義する方法で説明したように 、FluentAPIを使用しようとしました。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Parent>()
            .HasMany(p => p.Children)
            .WithOne(c => c.Parent);

        modelBuilder.Entity<Child>()
            .HasKey(c => new {c.Id, c.ParentId});

        base.OnModelCreating(modelBuilder);
    }

このアプローチでは正常に移行を生成できますが、 Childrenコレクションから子を削除しようとすると、次の例外が発生します。

System.InvalidOperationException:エンティティタイプ 'Parent'と 'Child'間の関連付けが切断されましたが、この関係の外部キーをnullに設定できません。依存エンティティを削除する必要がある場合は、カスケード削除を使用するように関係を設定します。

しかし、私はカスケードの削除を使用したくない、私は関係を識別するために使用したいと思います!

私が間違っていることを理解するのを手伝ってください。ありがとうございました!

受け入れられた回答

代わりに削除のカスケードを使用してください:

modelBuilder.Entity<Parent>()
    .HasMany(p => p.Children)
    .WithOne(c => c.Parent);
    .WillCascadeOnDelete(true);

https://msdn.microsoft.com/en-gb/data/jj591620.aspx


人気のある回答

万が一誰かがこのエラーを見た場合、私がどうやって私の解決したか教えてください。

更新を行うときは、EFで最初にデータベースを照会してデータモデルを取得し、次に変更を加えたドメインレイヤモデルをマップし(基本的にデータをフィールドにコピーする)、最後にDBContext updateメソッドを呼び出します。変更内容を保存。

私の問題は、私のモデル(データモデルではなく、ドメインモデル)にもサブオブジェクトがあることです。

だからここに(例えば)データ層モデルは次のとおりです。

public class Parent
{
   public int ChildId {get; set; }

   [ForeignKey("ChildId")]
   public virtual Child Child { get; set; }
}

そして、ドメイン層モデルは次のようになります。

public class Parent
    {
        public int ChildId { get; set; }
        //public Child Child { get; set; }  // this caused the error, keep reading if you want to know more.
    }

エラーが発生したときは、Autofacのランタイムマッパーを使用して、ドメインレイヤモデルのプロパティをデータレイヤモデルにマッピングしていました。ただし、ドメイン層モデルの子はnullだったため、データ層が無効になり、エラーが発生しました。

「エンティティタイプ 'Parent'と 'Child'の関連付けは切断されましたが、このリレーションシップの外部キーをnullに設定することはできません。従属エンティティを削除する必要がある場合は、カスケード削除を使用するようにリレーションシップを設定します。」


ちなみに、dbコンテキストクラスでは、次のような関係が定義されています。

modelBuilder.Entity<Parent>()
   .HasOne(a => a.Child)
   .WithMany()
   .HasForeignKey(p => p.ChildId)
   .OnDelete(DeleteBehavior.Restrict);

それは働いています。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ