实体框架:在通用过滤方法中使用DynamicLinq

时间:2016-07-27 18:58:44

标签: c# entity-framework linq generics dynamic-linq

我正在使用一种Filter方法开发一个通用的应用程序:

IQueryable<T> Filter<T>(IQueryable<T> query, Filter filter) where T : IDataBaseEntity

以下是传入的过滤器对象:

{
    Field: "Header.Title",
    Operator: "contains",
    Value: "asdf"
}

我有一个操作符开关(包含,&lt;,&gt;,==等)以不同的方式处理每个操作符,但我将只关注此示例的“包含”。

传入的“查询”变量是一个通用的接口列表,是我所有200个实体继承的接口。我甚至无法访问此命名空间中的实体类型。

在此示例中,“query”参数是实体“Page”的IQueryable。 DynamicLinq for Contains的典型示例如下:

Expression<Func<Page, bool>> exp = l => l.Contains(filter.Value);
query = query.Where("@0(it)", exp);

但是,我的应用程序的这一部分没有强类型,我的域名不知道“页面”是什么,而是使用继承的IDataBaseEntity作为Func&lt;&gt;第一种。我得到一个例外,因为“IDataBaseEntity”类型中没有“属性或字段'标题'”。我尝试了其他各种选择,但结果却是主要问题。

注意:我需要将它保持为IQueryable,并且出于性能原因,不要在任何时候将其转换为IEnumerable。该查询仅在过滤,排序和分页后运行(.AsEnumerable())。

是否可以使用名称空间中的接口类型对IQueryable运行动态linq,而该名称空间对我的实际实体类型一无所知?

1 个答案:

答案 0 :(得分:1)

根本不使用界面怎么样 - 动态Linq无论如何都要迟到了。您可以在Where上应用动态IQueryable<T>,结果将为IQueryable<T>

只要您能正确构建字符串谓词,以下内容就可以正常工作:

query = query.Where("Header.Title.Contains(@0)", filter.Value);