繁体   English   中英

如何使用通用存储库模式按类型有条件地过滤IQueryable

[英]How to conditionally filter IQueryable by type using generic repository pattern

我的通用存储库中有一个返回IQueryable<T>

    public virtual IQueryable<T> All
    {
        get
        {
            DbSet<T> set = Context.Set<T>();

            if (typeof(T).IsSubclassOf(typeof(OrganisationDependent)))
                return set.AsEnumerable()
                          .Cast<OrganisationDependent>()
                          .Where(x => x.OrganisationID == CurrentOrganisationID)
                          .AsQueryable()
                          .Cast<T>();

            return set;
        }
    }

if语句的原因是大多数但不是所有表都有一个OrganisationID ,我想确保用户只能看到他们所属组织的数据。 上面的代码工作,但为了使它工作,我不得不添加AsEnumerable()将数据拉入内存。 没有它,我收到错误消息

“无法将类型'Models.xxx'转换为'Models.OrganisationDependent'类型.LINQ to Entities仅支持转换EDM原语或枚举类型”

我的所有实体都直接继承ModelBaseOrganisationDependent

public abstract class OrganisationDependent : ModelBase
{
    public int OrganisationID { get; set; }

    public virtual Organisation Organisation { get; set; }
}

public abstract class ModelBase
{
    public int ID { get; set; }
}

有没有办法可以克服这个限制,以便当类型是OrganisationDependent的子类时,我过滤OrganisationID而不必将查询拉入内存?

最简单的选择可能是使用LINQ Expressions API动态构建过滤器表达式:

private static readonly PropertyInfo _organizationIdProperty 
    = typeof(OrganisationDependent).GetProperty("OrganisationID");

private static Expression<Func<T, bool>> FilterByOrganization<T>(int organizationId)
{
    var item = Expression.Parameter(typeof(T), "item");
    var propertyValue = Expression.Property(item, _organizationIdProperty);
    var body = Expression.Equal(propertyValue, Expression.Constant(organizationId));
    return Expression.Lambda<Func<T, bool>>(body, item);
}

public virtual IQueryable<T> All
{
    get
    {
        IQueryable<T> set = Context.Set<T>();
        if (typeof(T).IsSubclassOf(typeof(OrganisationDependent)))
        {
            var filter = FilterByOrganization<T>(CurrentOrganisationID);
            set = set.Where(filter);
        }

        return set;
    }
}

暂无
暂无

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

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