3

私は EF についてあまり知りませんが、いくつかのバグ修正を行う必要があります。バグの 1 つが次のように発生します。

  • を使用して親レコードを取得 (EF LINQ クエリ)ObjectContext
  • 一部のプロパティを変更する
  • 変更内容を保存

問題は、Get parent recordより具体的には、親のアクティブな子のみを取得することです。

これは現在のハックです:

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.Id == id
     select q).SingleOrDefault();

var atts = Context.Answers.Where(a => a.qId == id && a.active); // 1
data.Answers.Clear(); // 2
foreach (var att in atts)
{
    data.Answers.Add(att); // 3
}

何が起こるのですか:

  1. データベースからアクティブな子レコードを取得します
  2. 遅延読み込みのため、すべての添付ファイルがデータベースから取得されます。コレクションはすぐに消去されます。(EF トラッキングはこれらのレコードを「削除する」とマークしますか?)
  3. すべてのアクティブなレコードをループし、それらをコレクションに再度追加します (EF 追跡はこれらのレコードを「挿入する」とマークしますか?)

更新時に次の例外が発生します。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.

EFがコレクションをクリアしてから、同じレコードのいくつかを再度追加することについて混乱しているため、かなり一般的なエラーが発生すると思います。

私の質問: EF が私のレコードを削除して再挿入することを決して決定できないように、アクティブな子レコードのみを取得し、それらを「未変更」状態にする方法を教えてください。そして明らかに、更新時に非アクティブなレコードを失いたくありません。

答えではありません(またはそうですか?): SO と Google でよく見つかりますが、これを機能させることはできません:

Context.ContextOptions.LazyLoadingEnabled = false;

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.qId == id
     select new
     {
         Question = q,
         Answers = q.Answer.Where(a => a.active)
     }).ToArray().Select(q => q.Question).FirstOrDefault();

return data; // Does not contain the answers... :(
4

2 に答える 2

3

プロパティをロードしてからクリアする代わりに、プロパティを明示的にロードできます。これにより、不要なオブジェクトがオブジェクト グラフに読み込まれるのを防ぐことができるため、非アクティブなエンティティを切断してもエラーは発生しません。

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.Id == id
     select q).SingleOrDefault();

Context.Entry(data).Collection(b => b.Answers).Query()
    .Where(a => a.active)
    .Load();
于 2013-02-28T14:18:48.990 に答える
0

呼び出しdata.Answers.Clear()は十分ではありません。質問と回答の間の関連付けを削除するだけだからです。これらの回答も削除する場合は、コンテキストからも削除する必要があります。

foreach(var answer in data.Answers) {
  Context.DeleteObject(answer);
}

data.Answers.Clear();
于 2013-02-28T14:13:48.380 に答える