简体   繁体   English

基于实体类型的通用存储库应用过滤器

[英]Generic Repository apply filter based on entity type

I have a generic repository: 我有一个通用存储库:

 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;
       }
    }
 }

Some of my entities are tagable, ie implement ITagableEntity interface: 我的一些实体是可标记的,即实现ITagableEntity接口:

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

How can I implement if condition in ApplyTagFilter method ? 如何在ApplyTagFilter方法中实现if条件? What is the best way to approach it ? 最好的解决方法是什么? The way I tried does not work and looks ugly. 我尝试的方法行不通,看起来很丑。 Generic parameter T is of type IEntity, but ITagableEntities inherits from IEntity, thus I have to cast back and forth in order to apply the filter. 通用参数T的类型为IEntity,但是ITagableEntities继承自IEntity,因此我必须来回转换才能应用过滤器。

Any help would be greatly appreciated. 任何帮助将不胜感激。

Maybe you really consider creating some specific repository for taggable entities. 也许您真的考虑为可标记实体创建一些特定的存储库。

But if you want to make this code work — you can use cast. 但是,如果要使此代码正常工作,可以使用强制转换。

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

I solved the problem by implementing an idea proposed by FCin and VorobeY1326 . 我通过实施FCinVorobeY1326提出的想法解决了这个问题。 I marked GetQueryable() as protected virtual and overrode it in TagableRepository class. 我将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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM