使用动态构建的Expression过滤非泛型DbSet

时间:2017-01-31 00:34:21

标签: entity-framework linq generics expression-trees dbset

简介:

我有一个实现为Entity Framework DB上下文的外观的类。它开发用于保持向后兼容性,它模仿具有相同公共接口的类,但使用DTO而不是EF实体。

问题:

我在上面描述的类中有下一个方法。请参阅以下代码:

public IQueryable<T> FindBy<T>(Expression<Func<T, Boolean>> predicate) where T : BaseDto {

//GetDestinationType takes source type of some declared mapping and returns destination type
var entityType = Mapping.Mapper.GetDestinationType(typeof (T));

var lambda = Expression.Lambda(predicate.Body, Expression.Parameter(entityType));

// dbContext declared as class field and initialized in constructor
var query = dbContext.Set(entityType).Where(lambda); // <-- Cannot use non-generic expression/lambda

return query.ProjectTo<T>(mapper.ConfigurationProvider); }
  1. 我需要使用DTO作为In参数表达,并返回IQueryable,其中T:BaseDto作为结果
  2. 我需要使用EF实体将输入谓词转换为相同的谓词,如In parameter
  3. 我需要借助动态创建的Expression(谓词)
  4. 过滤非通用的EF DbSet

    主要问题

    是否可以借助动态创建的Expression(谓词)

    过滤非通用EF DBSet

    如果我需要使用其他方法,请给我一些胶水或进一步的指示。

1 个答案:

答案 0 :(得分:0)

问题已经解决了。解决方案很明显。而不是

var query = dbContext.Set(entityType).Where(lambda);

我可以写

var query = dbContext
                .Set(entityType)
                .ProjectTo<T>(mapper.ConfigurationProvider)
                .Where(predicate);

其中谓词是FindBy()方法的输入参数。

此代码将被成功编译,更重要的是,EF将为数据库构建最佳查询,该查询将包括查询正文中的Where()子句,因此它不会从数据库中获取完整的记录集侧。