通用存储库根据实体类型应用过滤器

时间:2017-09-07 19:33:55

标签: c# repository-pattern

我有一个通用存储库:

 public class Repository<T> : IRepository<T> where T : class, IEntity
 {
    public List<T> GetAllList(Expression<Func<T, bool>> filter)
    {
        return GetQueryable().Where(filter).ToList();
    }

    private IQueryable<T> GetQueryable()
    {
        IQueryable<T> query = Context.Set<T>().AsQueryable();
        query = ApplyTagFilter(query)
        return query;
    }

    private IQueryable<T> ApplyTagFilter(IQueryable<T> query)
    {
       //if T is ITagableEntity filter by token somehow
       if(typeof(ITagableEntity).IsAssignableFrom(typeof(T)))
       {
          //does not work and looks ugly :(
          return (query as IQueryable<ITagableEntity>)
             .Where(q => q.tagtoken > 10) as IQueryable<T>;
       }
       else
       {
           return query;
       }
    }
 }

我的一些实体是可标记的,即实现ITagableEntity接口:

public interface ITagableEntity : IEntity
{
    int tagtoken { get; set; }
}

如何在ApplyTagFilter方法中实现if条件?接近它的最佳方法是什么?我尝试的方式不起作用,看起来很难看。通用参数T的类型为IEntity,但ITagableEntities继承自IEntity,因此我必须来回转换才能应用过滤器。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

也许您真的考虑为可标记实体创建一些特定的存储库。

但是如果你想让这段代码有效 - 你可以使用强制转换。

return query.Cast<ITagableEntity>()
                .Where(q => q.tagtoken > 10)
                .Cast<T>();

答案 1 :(得分:0)

我通过实施 FCin VorobeY1326 提出的想法解决了这个问题。我将GetQueryable()标记为protected virtual并在TagableRepository课程中将其覆盖。

public class TagableRepository<T> : Repository<T> where T : class, ITagableEntity
{
    protected override IQueryable<T> GetQueryable()
    {
        return base.GetQueryable().Where(q => q.tagtoken > 10);
    }
}