Eu tenho a entidade Product e escrevo um método em uma classe de repositório (usando npgsql). Mas recebo um erro:
não pôde ser traduzido. Reescreva a consulta em um formato que possa ser traduzido ou alterne explicitamente para a avaliação do cliente inserindo uma chamada para 'AsEnumerable', 'AsAsyncEnumerable', 'ToList' ou 'ToListAsync'. Consulte https://go.microsoft.com/fwlink/?linkid=2101038 para obter mais informações. System.InvalidOperationException: A expressão LINQ 's => s.ProductId == EntityShaperExpression:
public class Product:IEntity
{
public string Id { get; set; }
public string SerialNo { get; set; }
public string Imei { get; set; }
public string Name { get; set; }
}
public class ProductInput
{
public string ProductId { get; set; }
public string SerialNo { get; set; }
public string Imei { get; set; }
}
public async Task<List<Product>> GetProducts(List<ProductInput> input) //EfCoreProductRepository.cs
{
var result = (from product in (await GetDbContextAsync()).Products
where input.Any(s => s.ProductId == product.Id && s.SerialNo == product.SerialNo && s.Imei == product.Imei)
select product).ToList();
return result;
}
Como devo editar minha consulta para evitar esse erro?
Parece que você está tentando recuperar linhas do banco de dados que correspondem às suas
input
linhas por vários critérios. Existem várias maneiras de fazer isso, como:input
dados em um parâmetro com valor de tabela (SQL Server) ou array digitado (Postgres), ou até mesmo em um blob de string JSON ( horrível ) e fazer umINNER JOIN
com esse parâmetro.WHERE
peça.input
em C# e executando consultas individuaisNa opinião deste autor, a Opção 2 (Consulta Linq construída dinamicamente) é a "melhor" geral aqui, então faça assim:
Primeiro, entenda
PredicateBuilder
- é uma dependência pequena que torna significativamente mais fácil construirOr
predicados com o Linq. É literalmenteclass
copiar e colar do site de Albahari.Em segundo lugar, use-o assim:
PredicadoBuilder
Para a posteridade, reproduzi
class PredicateBuilder
aqui: