0

ソフト削除をサポートする EF Code First ソリューションがあるため、エンティティを IsDeleted としてマークし、データベースから削除しません。削除済みとしてマークされたエンティティが API ユーザーに返されないように、関連オブジェクトのコレクション (遅延読み込み) を調整したいと考えています。

これが私が使用する簡単なアプローチです:

public class FilteredCollection<T> : ICollection<T> where T : DeletableEntity
{
    private List<T> _listWithDeleted = new List<T>();

    protected IEnumerable<T> FilteredItems
    {
        get { return _listWithDeleted.Where(e => e.IsDeleted == false); }
    }

    protected bool _IsReadOnly;

    public virtual T this[int index]
    {
        get
        {                
            return FilteredItems.ToList()[index];
        }
        set
        {
            FilteredItems.ToList()[index] = value;
        }
    }

    public virtual int Count
    {
        get
        {
            return FilteredItems.Count();
        }
    }

    public virtual bool IsReadOnly
    {
        get
        {
            return _IsReadOnly;
        }
    }

    public virtual void Add(T entityObject)
    {
        _listWithDeleted.Add(entityObject);
    }

    public virtual bool Remove(T entityObject)
    {
        if (FilteredItems.Contains(entityObject))
        {
            entityObject.IsDeleted = true;
            return true;
        }
        else
        {
            return false;    
        }
    }

    public bool Contains(T entityObject)
    {
        return FilteredItems.Contains(entityObject);
    }

    public virtual void CopyTo(T[] entityObjectArray, int index)
    {
        var list = FilteredItems.ToList();
        list.CopyTo(entityObjectArray, index);
    }

    public virtual void Clear()
    {
        foreach (var item in _listWithDeleted)
        {
            item.IsDeleted = true;
        }
    }

    public virtual IEnumerator<T> GetEnumerator()
    {
        return FilteredItems.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return FilteredItems.GetEnumerator();
    }
}

ICollection を実装したので、オブジェクトを内部的にフィルタリングします。ICollection の代わりにこのクラスを使用するので、フィルター処理されたエンティティが返されます。いくつかのテストを行ったところ、うまく機能しているように見えますが、このソリューションには満足していません。

このアプローチの欠点を教えてください。または、より良い方法を知っている場合は提案してください。

よろしくお願いします。

-ペトロ

4

1 に答える 1

1

アプリケーションでフィルタリングを行うため、これは間違ったソリューションです。データベースが拡大し、論理的に削除されたアイテムがますます増える場合は、フィルターを適用する前に常にそれらすべてをロードする必要があります。これはすぐに非常に大きなパフォーマンスの問題になる可能性があります。

データベースでフィルタリングを行う必要がありますが、それは遅延読み込みと熱心な読み込みに反します。ソリューションは条件付きマッピングにすることができます (削除されたアイテムのみがマップされません) が、プロパティのマッピングは許可されませんIsDeleted。ストアド プロシージャを使用してエンティティをソフト削除する必要があり、最初にコードでマップすることはできません。

最初に EF コード + ソフト削除を組み合わせることで、遅延読み込みと一括読み込みを完全に回避し、別のクエリを使用してフィルター処理されたデータを取得するか、明示的な読み込みを使用する必要があります。

于 2012-06-13T10:46:55.673 に答える