9

私は、設計者がすべてのテーブルを IsHistorical ビット列でマークすることを決定したデータベースで作業しています。適切なモデル化の考慮がなく、スキーマを変更する方法がありません。

これは、ナビゲーション プロパティとやり取りする CRUD 画面を開発する際に摩擦を引き起こしています。単純に Product を取得してその EntityCollection を編集することはできません。手動で IsHistorical チェックをあちこちに書かなければならず、気が狂いそうになります。

これまでのところ、追加が論理的に削除されているかどうかを確認するすべての手動チェックを作成したため、重複するエンティティを追加する代わりに、IsHistoric を切り替えることができるため、追加も恐ろしいものです。

私が検討した3つのオプションは次のとおりです。

  1. t4 テンプレートを変更して、IsHistorical チェックと同期を含めます。

  2. ObjectContext で削除と追加をインターセプトし、IsHistorical 列を切り替えてから、オブジェクトの状態を同期します。

  3. AssociationChanged イベントをサブスクライブし、そこで IsHistorical 列を切り替えます。

誰もこれを経験したことがありますか、または最も痛みのないアプローチを推奨できますか?

注:はい、わかっています。これは悪いモデリングです。あなたが持っている論理的な削除に関する同じ記事を読みました。この要件に対処しなければならないのは面倒ですが、対処します。データベース内のすべてのナビゲーション プロパティに対して同じコードを記述せずに、論理的な削除を処理する最も簡単な方法が欲しいだけです。

注#2 LukeLedの答えは技術的には正しいですが、あなたを本当に悪い貧乏人のORM、グラフのないパターンに強制します。問題は、「削除された」オブジェクトをすべてグラフから取り出し、それぞれに対して Delete メソッドを呼び出す必要があるという事実にあります。それは、手動の儀式的なコーディングをそれほど節約するつもりはありません。手動の IsHistoric チェックを記述する代わりに、削除されたオブジェクトを収集してそれらをループ処理しています。

4

3 に答える 3

8

コードで汎用リポジトリを使用しています。次のようにできます。

public class Repository<T> : IRepository<T> where T : EntityObject
{
    public void Delete(T obj)
    {
        if (obj is ISoftDelete)
            ((ISoftDelete)obj).IsHistorical = true
        else
            _ctx.DeleteObject(obj);
    }

List()メソッドも IsHistorical でフィルタリングします。

編集:

ISoftDeleteインターフェース:

public interface ISoftDelete
{
    bool IsHistorical { get; set; }
}

エンティティ クラスは部分的であるため、ISoftDelete として簡単にマークできます。部分的なクラス定義を別のファイルに追加する必要があります:

public partial class MyClass : EntityObject, ISoftDelete
{

}
于 2009-12-21T22:51:01.470 に答える
5

お気づきだと思いますが、スキーマを変更できない場合、この問題に対する優れた解決策はありません。リポジトリ オプションが気に入らない場合 (ただし、それを却下するのを少し急いでいるわけではないのではないかと思います)、私が思いつく最善の方法を次に示します。

  1. 扱うObjectContext.SavingChanges
  2. ObjectStateManagerそのイベントが発生したら、削除された状態のオブジェクトを探してトロールします。プロパティがある場合は、それをIsHistorical設定し、オブジェクトの状態を変更済みに変更します。

これは、関連付け/関係に関しては扱いにくいものになる可能性がありますが、多かれ少なかれあなたが望むことをしていると思います.

于 2009-12-22T13:21:36.577 に答える