.net Entity Framework Core 7:重写查询的形式,可以翻译错误时,我使用一个表达式的集合

eqfvzcg8  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(142)

我想在查询中使用一个表达式来定义一个投影,并根据从用户接收到的参数在查询中设置条件。
这是一个表达式:

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?
谢谢

vlju58qv

vlju58qv1#

只需要使用像Automapper/Mapster/Mapster这样的Map器。

var config = new MapperConfiguration(cfg => 
{
    cfg.CreateMap<MyEntity, MyDto>();
});

字符串
然后:

return await _context.DbSet
.ProjectTo<MyDto>(config)
.ToListAsync();


如果需要对Map进行自定义,例如将相关实体平铺到DTO列中,则可以使用ForMember()

var config = new MapperConfiguration(cfg => 
{
    cfg.CreateMap<MyEntity, MyDto>()
        .ForMember(x => x.SubjectName, opt => opt.MapFrom(src => src.Subject.Name));
});


这告诉Automapper,要在DTO中填充SubjectName,请转到实体的Subject属性并获取名称。Automapper可以按照约定自动Map这些名称,尽管我通常选择特定以避免意外。
使用ProjectTo()将结果表达式发送到SQL,就像运行Select一样,所以不需要急于加载相关实体或使用AsNoTracking。(与使用Map()相反,它将在内存中执行Map)

相关问题