4

私はGeneric RepositoryパターンでEF6を使用しています。最近、複合エンティティを一度に削除しようとして問題が発生しました。ここでは単純化したシナリオである:EF eagerly loadingナビゲーションプロパティの問題

public class Parent 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Child> Children { get; set; } 
} 
public class Child 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    [ForeignKey("Parent")] 
    public int ParentId { get; set; } 

    public virtual Parent Parent { get; set; } 
} 

私はこのような何かやっている関連子供と親エンティティを削除するために:

public virtual T GetById(int id) 
{ 
    return this.DBSet.Find(id); 
} 
public virtual void Delete(T entity) 
{ 
    DbEntityEntry entry = this.Context.Entry(entity); 

    if (entry.State != EntityState.Deleted) 
    { 
     entry.State = EntityState.Deleted; 
    } 
    else 
    { 
     this.DBSet.Attach(entity); 
     this.DBSet.Remove(entity); 
    } 
} 

まず、私はIDによって親オブジェクトを検索し、削除するためにそれを渡しますメソッドを削除して状態を変更します。 context.SaveChanges()は最終的に削除をコミットします。

これは正常に機能しました。 FindメソッドはParentオブジェクトをプルアップして、Deleteが有効になっているので、削除操作はカスケードしています。

しかし、私は子供のクラスで別のプロパティを追加した瞬間:

[ForeignKey("Gender")] 
public int GenderId { get; set; } 

public virtual Gender Gender { get; set; } 

何らかの理由では、EFはParent.Find()メソッドに関連した子供たちを引っ張って始めました。このため、次のエラーが表示されます。

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

変更を元に戻しても(Genderプロパティを削除しても)、問題は解決されません。私はこの奇妙な行動を理解することができません!

私がしたいのは、子どもと共に親オブジェクトを削除することです。 あり、その周りにいくつかの解決策があるが、どれも本当に私の目的を果たしていない:falseに遅延読み込み

  1. 電源を入れます - 偽= this.Configuration.LazyLoadingEnabled。これは動作しますが、私の実際のアプリケーションでは、このプロパティが必要です。
  2. すべての子を最初に反復し、それらを削除して、親を削除します。これは最善の回避策と思われ、非常に冗長です。
  3. EntityStateをDeletedに変更するのではなく、Remove()を使用します。 EntityStateが監査のために変更を追跡する必要があります。

EFが関連エンティティを読み込んでいる理由について説明してもらえますか?

+0

元に戻したら、DBも元に戻しましたか?あなたの問題はおそらくDBに関係しています。 – Sefe

+0

ええ、しました。私はDBを落として、それを再作成しました。 –

+0

私はSQLクエリで親エンティティを削除することができ、子供の削除作業時にカスケードすることができるので、DB関連の疑いがあります。 –

答えて

2

この問題は、コンテキストのライフサイクルに関連しているようです。私はUnit Of Workを使用しており、それをninjectを使用して私のサービス層に注入しています。

kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); 

UnitwiseクラスはIDisposableを実装します。

ブロックされていないコメントのコードがスローされ、エラーが発生します。この呼び出しの前のコントローラーメソッドは、CustomViewエンティティー(Parentと同様の構造を持ち、子のリストを持つ)をロードします。その後のユーザー操作をトリガーして、そのビューを削除することができます。

私はこれがコンテキストが処分されていないことと関係していると思います。たぶんこれはNinjectやUnitOfWorkと何か関係がありますが、私はまだピンポイントできませんでした。 GetById()は、コンテキストキャッシュなどからエンティティ全体を取得している可能性があります。

しかし、上記の回避策は私には役に立ちます。誰かを助けるかもしれないようにそれをそこに置くだけです。

+0

Autofacを使用する - ライフタイム、スコープ、廃棄、作業単位(要求ごとに)に対する解決策ははるかに成熟して分かりやすくなります。 –

+0

換言すれば、投稿全体が間違っていて、EFとは何の共通点もありませんが、パターンや注射などはありません。賞金の有効期限が切れると、誤解を招くだけなので質問を削除する必要があります。誰か。 –

関連する問題