Usare la libreria PredicateBuilder per eseguire query tramite Entity Framework che usano or su più campi

di Stefano Mostarda, in LINQ, Entity Framework,

Molto spesso capita di avere una lista di id e di dover recuperare dal database i record che corrispondono a quegli id. Questa query in LINQ è estremamente semplice come si vede dal codice.

//c#
var items = new[] { 1,2,3 }; 
var rec = await ctx.People.Where(c => items.Contains(c.Id)).ToListAsync();

--sql
select * from People where Id in (1,2,3);

Questo codice è semplice e funziona benissimo quando la chiave della tabella è composta da un solo campo, ma cosa succede se la chiave della tabella è composta da più campi? In questi casi, la Contains non è una soluzione e quindi dobbiamo cercare altre strade. Una possibile strada è quella di usare più Or concatenate.

var r = ctx.People
  .Where(c => (c.Id1 == 1 && c.Id2 == 1) || (c.Id1 == 1 && c.Id2 == 2))
  .ToListAsync();

Questa tecnica va bene quando sappiamo a priori il numero di chiavi che abbiamo, ma quando ci arriva una lista come possiamo costruire la query dinamicamente? Per questa esigenza ci possono venire in aiuto diverse librerie. Una di queste è LinqKit.Core (disponibile su NuGet). Tramite questa libreria possiamo scrivere il seguente codice.

//c#
var ids = new [] { new Id { Id1 = 1, Id2 = 1 }, new Id { Id1 = 1, Id2 = 2 } };
var predicate = PredicateBuilder.New<Person>(false);
foreach (var key in ids)
{
    predicate = predicate.Or(c => c.Id1 == key.Id1 && c.Id2 == key.Id2);
}
var people = await ctx.People.Where(predicate).ToListAsync();

--sql
select * from People where (id1 = 1 and id2 = 1) or (id1 = 1 and id2 = 2)

La prima riga del codice istanza un oggetto che conterrà la nostra espressione finale. Nel ciclo aggiungiamo alla nostra espressione una Or che al suo interno fa una And tra i campi chiave. Alla fine passiamo la nostra espressione alla Where ed eseguiamo la query.

Commenti

Visualizza/aggiungi commenti

| Condividi su: LinkedIn, Facebook

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi