我想在查询中使用一个表达式来定义一个投影,并根据从用户接收到的参数在查询中设置条件。
这是一个表达式:
private Expression<Func<MyDTO, MyDTO>> GetProjectionForSearch()
{
return x => new MyDTO
{
Id = x.Id,
Property1 = x.Property1,
Property2 = x.Property2,
};
}
字符串
这是它的工作原理:
return await _context.DbSet
.AsNoTracking()
.Select(GetProjectionForSearch())
.ToListAsync();
型
然而,我想根据我从用户那里收到的参数设置一些过滤器。到目前为止,我一直使用这种方式:
IQueryable<MyDTO> myIq = _context.DbSet
.Select(GetProyeccionFacturaPorBusqueda());
if (param1 != null)
{
myIq = myIq.where(x => x.Property1 == param1);
}
if (param2 != null)
{
myIq = myIq.where(x => x.Property2 == param2);
}
return await myIq.ToListAsync();
型
但是当我以这种方式设置where条件时,我得到了这个错误:
要么以可转换的形式重写查询,要么通过插入对“AsEnumerable”、“AsAsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算
我如何使用投影并以动态的方式设置where?
谢谢
1条答案
按热度按时间vlju58qv1#
只需要使用像Automapper/Mapster/Mapster这样的Map器。
字符串
然后:
型
如果需要对Map进行自定义,例如将相关实体平铺到DTO列中,则可以使用
ForMember()
:型
这告诉Automapper,要在DTO中填充SubjectName,请转到实体的Subject属性并获取名称。Automapper可以按照约定自动Map这些名称,尽管我通常选择特定以避免意外。
使用
ProjectTo()
将结果表达式发送到SQL,就像运行Select
一样,所以不需要急于加载相关实体或使用AsNoTracking
。(与使用Map()
相反,它将在内存中执行Map)