我正在开发一个具有一个Filter方法的通用应用程序:
IQueryable<T> Filter<T>(IQueryable<T> query, Filter filter) where T : IDataBaseEntity
以下是传入的筛选器对象:
{
Field: "Header.Title",
Operator: "contains",
Value: "asdf"
}
我为运算符(contains、<、>、==等)提供了一个开关,以不同的方式处理每一个,但在本例中,我只关注"contains"。
传入的"query"变量是接口的通用列表,我的所有200个实体都继承自该接口。我甚至无法访问这个名称空间中的实体类型。
在本例中,"query"参数是实体"Page"的IQueryable。DynamicLinq for Contains的一个典型示例如下:
Expression<Func<Page, bool>> exp = l => l.Contains(filter.Value);
query = query.Where("@0(it)", exp);
然而,我的应用程序的这一部分不是强类型的,我的域不知道什么是"Page",而是使用继承的IDataBaseEntity作为Func<>第一类。我收到异常,因为"类型'IDataBaseEntity'中不存在属性或字段'Header'"。我尝试了各种其他选择,但最终这是主要问题。
注意:我需要将其保持为IQueryable,并且出于性能原因,不想在任何时候将其变成IEnumerable。查询仅在筛选、排序和分页之后运行(.AsEnumerable())。
有可能在一个对我的实际实体类型一无所知的命名空间中使用接口类型对IQueryable运行动态linq吗?
完全不使用接口怎么样?Dynamic Linq无论如何都是后期绑定的。您可以在IQueryable<T>
上应用动态Where
,结果将是IQueryable<T>
。
一旦您能够正确地构建字符串谓词,以下内容就应该起作用:
query = query.Where("Header.Title.Contains(@0)", filter.Value);