【问题标题】:EF 4.1 Code First filtering lazy loaded collectionsEF 4.1 Code First 过滤延迟加载的集合
【发布时间】:2012-06-13 10:35:16
【问题描述】:

我有支持软删除的 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,因此将过滤后的实体返回给我。 我做了一些测试,看起来效果不错,但我对这个解决方案感到不舒服。

您能否告诉我这种方法的缺点,或者如果您知道更好的方法,请提出建议。

先谢谢了,

-石油

【问题讨论】:

    标签: entity-framework entity-framework-4 filter ef-code-first lazy-loading


    【解决方案1】:

    这是错误的解决方案,因为它会在您的应用程序中进行过滤。如果您的数据库会增长并且会有越来越多的软删除项目,您将始终需要在应用过滤器之前加载所有这些项目。这很快就会成为非常大的性能问题。

    您应该在数据库中进行过滤,但这不利于延迟加载和急切加载。解决方案可以是条件映射(只会映射未删除的项目),但它不允许您映射 IsDeleted 属性 - 您必须使用存储过程软删除您的实体,而这反过来又不能先用代码映射。

    结合使用 EF 代码优先 + 软删除,您应该完全避免延迟加载和急切加载,并且使用单独的查询来获取过滤数据或使用显式加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多