【问题标题】:With a generic repository for entity framework, how do I query entities which implement a specific interface?使用实体框架的通用存储库,如何查询实现特定接口的实体?
【发布时间】:2014-04-24 04:56:02
【问题描述】:

我在实体框架中使用存储库模式,并且已经实现了一个通用存储库。

但对于某些类型的实体,我不想从数据库中删除记录,而是想将 IsDeleted 布尔值设置为 true。

为此,我创建了这个简单的界面:

IEntityProtectedDelete.cs

public interface IEntityProtectedDelete
{
    bool IsDeleted { get; set; }
}

是这样在我的实体上实现的:

Queue.cs

public class Queue : IEntityProtectedDelete
{
    public Queue() 
    {
        IsDeleted = false;
    }

    [Key]
    public int QueueId { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public bool IsDeleted { get; set; }
}

以下是我正在使用的通用存储库的一部分。 Delete 方法按预期工作,并在使用上述接口时将IsDelete 属性设置为 true。

但是,如果实体实现IEntityProtectedDelete,我不太清楚如何正确查询数据库。

GenericRepository.cs

public class GenericRepository<T> where T : class
{
    protected DBContext context;
protected IDBSet dbSet;

    public GenericRepository(IContext context)
    {
        this.context = context;
    this.dbSet = context.Set<T>();
    }

    public virtual void Delete(T entity)
    {
        dbSet.Attach(entity);
        if (entity is IEntityProtectedDelete)
        {
            (entity as IEntityProtectedDelete).IsDeleted = true;
            context.Entry(entity).State = EntityState.Modified;
        }
        else { dbSet.Remove(entity); }  
    }

    public virtual IEnumerable<T> GetAll()
    {
        if (typeof(IEntityProtectedDelete).IsAssignableFrom(typeof(T)))
        {
            return context.Set<T>().OfType<IEntityProtectedDelete>().Where(e => e.IsDeleted == false).ToList() as IEnumerable<T>;
        }
        else { return context.Set<T>().ToList(); }
    }
}

在GetAll()方法中,OfType&lt;&gt;抛出异常:

'IEntityProtectedDelete' is not a valid metadata type for type filtering operations. Type filtering is only valid on entity types and complex types."

如果这不起作用,我还有什么其他选择?

【问题讨论】:

    标签: c# linq entity-framework generics


    【解决方案1】:

    实体框架的软删除模式已在 SO 上进行了讨论,并在此处描述了可接受的解决方案

    http://www.wiktorzychla.com/2013/10/soft-delete-pattern-for-entity.html

    诀窍是将您的IsDeleted 定义为鉴别器列,以便 EF 自动附加过滤子查询。

    【讨论】:

    • “软删除”,我正在寻找的名称。感谢您提供的信息,这当然非常有帮助。这种方法的一个限制似乎是,由于鉴别器,EF 将在所有查询中排除这些记录。我需要能够将这些记录包含在“GetById()”场景中,以及其他一些用于报告的案例中。此外,我可能需要一个实际删除记录的 Purge 函数。
    • @dlux:这可以通过两个上下文类轻松实现。基类通常包括鉴别器。子类定义软删除。使用工厂,您可以在两者之间切换。由于直接继承,您不需要定义模型两次。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多