Uno dei task più frequenti per uno sviluppatore backend è quello di implementare un metodo di ricerca di una qualsiasi entità su una base dati utilizzando un set di filtri opzionali. Tipicamente. si finisce per craere un metodo che prende in input un oggetto contenente tali filtri, che ha una forma simile a questa:
public class SearchCriteria { public string? FirstName { get; set; } public string? LastName { get; set; } public string? Email { get; set; } public bool? Enabled { get; set; } ... }
Il metodo che effettua la ricerca di utenti su una tabella del database utilizzando un DbContext di EF Core sarà simile a questo:
async Task<IEnumerable<UserEntity>> SearchUsers(SearchCriteria searchCriteria) { var query = _tmsContext.Users; if(!string.IsNullOrWhiteSpace(searchCriteria.FirstName)) query = query.Where(x => x.FirstName.Contains(searchCriteria.FirstName!)); if(!string.IsNullOrWhiteSpace(searchCriteria.LastName)) query = query.Where(x => x. LastName.Contains(searchCriteria. LastName!)); if(!string.IsNullOrWhiteSpace(searchCriteria.Email)) query = query.Where(x => x. Email.Contains(searchCriteria. Email!)); if(searchCriteria.Enabled.HasValue) query = query.Where(x => x.Enabled == searchCriteria.Enabled); return await query.ToListAsync(); }
Per noi dev, less is more e questo vale soprattutto per la quantità di codice da scrivere. Per scrivere meno codice, possiamo creare un extension method che prende in input la condizione in base alla quale applicare il filtro e il filtro. Nel metodo verifichiamo che la condizione sia a true e in caso positivo applichiamo il filtro, in caso negativo non facciamo nulla.
public static class LinqExtensions { public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition, Expression<Func<TSource, bool>> predicate) => condition ? source.Where(predicate) : source; }
A questo punto, il metodo di ricerca può essere trasformato come segue.
async Task<IEnumerable<UserEntity>> SearchUsers(SearchCriteria searchCriteria) => _tmsContext.Users .WhereIf(!string.IsNullOrWhiteSpace(searchCriteria.FirstName), x => x.FirstName.Contains(searchCriteria.FirstName!)) .WhereIf(!string.IsNullOrWhiteSpace(searchCriteria.LastName), x => x.LastName.Contains(searchCriteria.LastName!)) .WhereIf(!string.IsNullOrWhiteSpace(searchCriteria.Email), x => x.Email.Contains(searchCriteria.Email!)) .WhereIf(searchCriteria.Enabled.HasValue, x => x.Enabled == searchCriteria.Enabled) .ToListAsync();
Il codice del metodo di ricerca che utilizza il nostro extension method è estremamente più compatto e, a seconda dei propri gusti, anche più leggibile.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire una query su SQL Azure tramite un workflow di GitHub
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Creazione di componenti personalizzati in React.js con Tailwind CSS
Utilizzare ChatGPT con Azure OpenAI
Usare lo spread operator con i collection initializer in C#
Limitare le richieste lato server con l'interactive routing di Blazor 8
Controllare gli accessi IP alle app con Azure Container Apps
Gestire i null nelle reactive form tipizzate di Angular
Eseguire query manipolando le liste contenute in un oggetto mappato verso una colonna JSON
Miglioramenti agli screen reader e al contrasto in Angular
Elencare le container images installate in un cluster di Kubernetes
Usare le variabili per personalizzare gli stili CSS
I più letti di oggi
- Evitare il flickering dei componenti nel prerender di Blazor 8
- Rilasciata la Beta 2 di Visual Studio 2008
- tra pochi minuti inizia la keynote della seconda giornata. seguila live su http://aspitalia.com/mix-11 #mix11
- .@dbochicchio ora su #aspnetcore 2 a #netconfit https://aspit.co/netconf-17
- Utilizzare angular-cli per creare una direttiva in Angular 2
- Windows Vista: il ritorno di WinFS con la beta1
- .@CristianCivera tra poco su #azure con i suoi tips&tricks per lo sviluppatore web: https://aspit.co/web15-live #aspilive
- Le novità di C# 10