EF Core 3.1 - 如何根据参数进行过滤?
EF Core 3.1 - how to do filtering based on parameters?
在 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(我假设您无法在 Select
之后添加 Where
)。
如果我尝试在过滤后添加 Select
,编译器告诉我他无法将 IQueryable<BusinessUnit>
转换为 IQueryable<BuViewModel>
。
如果我尝试显式声明 IQueryable<BuViewModel> 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,而是在处理 IEnumerable。这是不正确的,因为您希望 SQL 为您过滤数据。不要将所有内容都加载到内存中。
在 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(我假设您无法在 Select
之后添加 Where
)。
如果我尝试在过滤后添加 Select
,编译器告诉我他无法将 IQueryable<BusinessUnit>
转换为 IQueryable<BuViewModel>
。
如果我尝试显式声明 IQueryable<BuViewModel> 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,而是在处理 IEnumerable。这是不正确的,因为您希望 SQL 为您过滤数据。不要将所有内容都加载到内存中。