Asp.net core EF Core 3.1-如何根据参数进行过滤?

Asp.net core EF Core 3.1-如何根据参数进行过滤?,asp.net-core,entity-framework-core,ef-core-3.1,Asp.net Core,Entity Framework Core,Ef Core 3.1,在ef core 2.2中,我可以执行以下操作: var query = _dbContext.BusinessUnits .Include(a => a.Parent) .Include(a => a.Region) .AsNoTracking().Select(x => new BUViewModel(x)); if (!string.IsNullOrWhiteSpace

在ef core 2.2中,我可以执行以下操作:

        var query = _dbContext.BusinessUnits
            .Include(a => a.Parent)
            .Include(a => a.Region)
            .AsNoTracking().Select(x => new BUViewModel(x));
        if (!string.IsNullOrWhiteSpace(dto.Name))
        {
            query = query.Where(x => x.Name.ToLower().Contains(dto.Name.ToLower()));
        }

        if (dto.Level != null)
        {
            query = query.Where(x => x.Level == dto.Level);
        }


        if (dto.ParentId != null)
        {
            query = query.Where(x => x.ParentId == dto.ParentId);
        }
现在,3.1似乎无法将其转换为SQL(我假设您不能在
选择
之后添加
Where
)。 如果我尝试在过滤后添加
Select
,编译器会告诉我他无法将
IQueryable
转换为
IQueryable
。 如果我试图显式声明
IQueryable query=…
,我必须在
Where
子句之前编写
Select
(这样做行不通)。
这里最好的方法是什么?

问题从这一行开始。IQueryable构造一个SQL查询,因此:

   .Select(x => new BUViewModel(x))
Iqueryable无法调用构造函数。因此,要解决这个问题,请手动执行

.Select(x=> new BUViewModel(){
               Id = x.Id,
               Name = x.Name // etc

            })
但是为什么构造器不工作呢?因为你可以在构造函数中编写你想要的任何代码。EF将无法转换为SQL查询。假设您可以编写这样的构造函数

public BUViewModel(int id){
    var apiToken = _serviceCallApi(id);
}
例如,上面的示例在构造对象时调用api(这只是一个示例)。不可能将此逻辑转换为查询。有像automapper这样的工具可以自动映射实体


我的猜测很简单,你不是在处理IQueryable,而是在处理IEnumarable。这是不正确的,因为您希望SQL为您过滤数据。不要加载内存中的所有内容。

尝试在最后移动Select,EF将理解您的where子句。尝试过它,将无法工作,因为它的类型与我声明的类型不同,例如var query=context.BusinessUnits.AsQueryable();然后,您可以使用此可查询项再次查询select。您确定在2.2中,它是在SQL中运行查询,而不是将所有数据转储到内存中并在那里运行吗?我不知道任何LINQtoSQL引擎如何能够将Select转换为SQL。@Jimbot,这就是我所尝试的