9

このコードは、データベースファーストのEntityFrameworkレイヤーを使用する.Net4.5を対象としたWindowsサービスにあります。

var existingState = DataProcessor.GetProcessState(workerId);

existingState.ProcessStatusTypeId = (int)status;
existingState.PercentProgress = percentProgress;
existingState.ProgressLog = log;

DataProcessor.UpdateProcessState(existingState);

そして、同じソリューションのデータ処理クラスのこのコード:

public ProcessState GetProcessState(int id)
{
    using (var context = new TaskManagerEntities())
    {
        var processes = (from p in context.ProcessStates.Include("ProcessType").Include("ProcessStatusType")
                         where p.IsActive && p.ProcessStateId == id
                         select p);

        return processes.FirstOrDefault();
    }
}

public ProcessState UpdateProcessState(ProcessState processState)
{
    using (var context = new TaskManagerEntities())
    {
        context.ProcessStates.Add(processState);
        context.Entry(processState).State = System.Data.EntityState.Modified;
        context.SaveChanges();
    }

    return processState;
}

ProcessStateは、他の2つのクラス、ProcessStatusTypeとProcessTypeの親です。そのコードをWindowsサービスで実行すると、レコードが取得され、エンティティが更新されて保存されます。上記のコードではProcessTypeの子が使用されていないという事実にもかかわらず、ProcessStateエンティティの保存が実行されると、EFはProcessTypeテーブルに挿入を実行し、そのテーブルに新しいレコードを作成します。次に、ProcessStatusエンティティのFKを変更して、新しい子を指すようにし、データベースに保存します。

これは、本質的に同一のFK親子関係で設定されたProcessStatusTypeテーブルでは行われません。

これで、不要な同一のProcessTypeエントリでいっぱいのデータベースができましたが、なぜこれが発生しているのかわかりません。これが私の最初のEFプロジェクトであるため、私には見えない明らかな間違いを犯しているような気がします。呼び出しの合間にコンテキストを期限切れにすることを許可しているが、同じエンティティを維持しているという問題はありますか?

4

1 に答える 1

5

Add を使用すると、すべての要素の状態が [追加済み] に設定され、子要素が挿入されます。この要素に EntityState.Modified を指定すると、親要素は挿入されません。

Add を使用するのではなく、UpdateProcessState で以下を使用してみてください。

context.ProcessStates.Attach(processState);
context.Entry(processState).State = EntityState.Modified;
context.SaveChanges();

Attach はすべての要素の状態を Unchanged に設定し、親要素に Modified を指定することで、この要素のみを更新する必要があることを示します。

別の注意事項。Include(x => x.ProcessType)ではなく、厳密に型指定された を使用する必要がありますInclude("ProcessType")

于 2013-02-15T21:24:18.927 に答える