In .NET 10 è possibile gestire la paginazione e l'ordinamento dinamico di collection in memoria (anche lette da Database) con un semplice extension method:

C#

using System.Linq.Dynamic.Core;

public static class IQueryableExtension
{
    /// <summary>
    /// es,: GET https://localhost:7182/api/test?page=1&size=5&orderBy=idcLiente&direction=desch
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="source"></param>
    /// <param name="page">pagina iniziale parte da 1</param>
    /// <param name="size">dimensione pagina</param>
    /// <param name="validSortColumns">colonne valide per il sort, la prima è il default ASC se non c'è match</param>
    /// <param name="orderBy">nome colonna case insensitive</param>
    /// <param name="direction">ASC | DESC</param>
    /// <param name=""></param>
    /// <returns></returns>
    public static IQueryable<T> PagingAndSorting<T>(this IEnumerable<T> source, int page, int size, string[]? validSortColumns = null, string? orderBy = null, string? direction = null)
    {
        if (page < 1) page = 1;
        if (size > 5000) size = 5000;
        else if (size < 1) size = 1;

        var query = source.AsQueryable();

        if (validSortColumns != null && validSortColumns.Length > 0 && !string.IsNullOrWhiteSpace(orderBy))
        {
            bool descending = direction?.Equals("desc", StringComparison.OrdinalIgnoreCase) ?? false;
            if (!validSortColumns.Contains(orderBy, StringComparer.OrdinalIgnoreCase))
            {
                // setto la prima colonna come default asc
                orderBy = validSortColumns[0];
                descending = false;
            }

            query = query.OrderBy(orderBy + (descending ? " DESC" : " ASC"));
        }

        return query
            .Skip((page - 1) * size)
            .Take(size);
    }
}
l'extension method PagingAndSorting va usato in questo modo:

C#

static string[] validSortColumns = ["IDCliente", "Nome", "Cognome", "Email", "Genere", "Eta", "Citta", "DataIscrizione", "TotaleSpeso", "NumeroOrdini", "StatoAccount"];

[HttpGet("")]
public object GetAll(int page, int size = 25, string? orderBy = null, string? direction = null)
{
    List<TestItem> item = JsonSerializer.Deserialize<List<TestItem>>(DATASET, jsonOptions) ?? [];

    return item.PagingAndSorting<TestItem>(page, size, validSortColumns, orderBy, direction);
}

const string DATASET = """
    [
        { "idCliente": 1, "nome": "Alessandro", "cognome": "Rossi", "Email": "alessandro.rossi.1@example.com", "Genere": "M", "Eta": 42, "Citta": "Milano", "dataIscrizione": "2023-01-15", "totaleSpeso": 1250.45, "numeroOrdini": 12, "statoAccount": "Attivo" },
        { "idCliente": 2, "nome": "Giulia", "cognome": "Bianchi", "Email": "giulia.bianchi.2@example.com", "Genere": "F", "Eta": 31, "Citta": "Roma", "dataIscrizione": "2023-02-18", "totaleSpeso": 450.20, "numeroOrdini": 5, "statoAccount": "Attivo" },
    ...
    ]
    """;

private readonly JsonSerializerOptions jsonOptions = new() { PropertyNameCaseInsensitive = true };

internal record TestItem
{
    public int IDCliente { get; set; }
    public string Nome { get; set; } = string.Empty;
    public string Cognome { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public char Genere { get; set; }
    public int Eta { get; set; }
    public string Citta { get; set; } = string.Empty;
    public DateTime DataIscrizione { get; set; }
    public double TotaleSpeso { get; set; }
    public int NumeroOrdini { get; set; }
    public string StatoAccount { get; set; } = string.Empty;
}
posso anche filtrare con Where:

C#

[HttpGet("")]
public object GetAll(int page, int size = 25, string? orderBy = null, string? direction = null)
{
    List<TestItem> item = JsonSerializer.Deserialize<List<TestItem>>(DATASET, jsonOptions) ?? [];

    return item
            .Where(x => string.IsNullOrWhiteSpace(x.Email) == false)
            .PagingAndSorting<TestItem>(page, size, validSortColumns, orderBy, direction);
}
ATTENZIONE: molto importante, da usare con solo con piccole collection/dataset di poche centinaia di righe.
Per grosse tabelle con migliaia o più righe, meglio gestire la paginazione lato Database, vedi Paginazione in T-SQL con SQL Server 2012.
Tags:
C#242 Linq1 Database77
Potrebbe interessarti anche: