sql-order-by - Più "ordina per" in LINQ




(7)

Usando LINQ non-lambda, query-sintassi, puoi farlo:

var movies = from row in _db.Movies 
             orderby row.Category, row.Name
             select row;

[MODIFICA per indirizzare il commento] Per controllare l'ordinamento, utilizzare le parole chiave in ordine ascending (che è l'impostazione predefinita e quindi non particolarmente utile) o descending , in questo modo:

var movies = from row in _db.Movies 
             orderby row.Category descending, row.Name
             select row;

Ho due tabelle, movies e categories e ottengo una lista ordinata per categoryID prima e poi per Name .

La tabella del film ha tre colonne, ID, Nome e IDCategoria . La tabella delle categorie due ha colonne, ID e Nome .

Ho provato qualcosa di simile al seguente, ma non ha funzionato.

var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })

C'è almeno un altro modo per farlo usando LINQ, sebbene non sia il più semplice. Puoi farlo usando il metodo OrberBy() che usa un OrberBy() . Per prima cosa devi implementare un IComparer per la classe Movie come questo:

public class MovieComparer : IComparer<Movie>
{
    public int Compare(Movie x, Movie y)
    {
        if (x.CategoryId == y.CategoryId)
        {
            return x.Name.CompareTo(y.Name);
        }
        else
        {
            return x.CategoryId.CompareTo(y.CategoryId);
        }
    }
}

Quindi puoi ordinare i film con la seguente sintassi:

var movies = _db.Movies.OrderBy(item => item, new MovieComparer());

Se è necessario passare l'ordine alla discesa per uno degli elementi, basta cambiare di conseguenza la xey all'interno del metodo Compare() di MovieComparer .


Se si utilizza un repository generico

> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();

altro

> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();

Questo dovrebbe funzionare per te:

var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)

Ho creato alcuni metodi di estensione (sotto) in modo da non doversi preoccupare se un IQueryable è già ordinato o meno. Se vuoi ordinare per più proprietà, fallo come segue:

// We do not have to care if the queryable is already sorted or not. 
// The order of the Smart* calls defines the order priority
queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);

Ciò è particolarmente utile se si crea l'ordinamento in modo dinamico, da un elenco di proprietà da ordinare.

public static class IQueryableExtension
{
    public static bool IsOrdered<T>(this IQueryable<T> queryable) {
        if(queryable == null) {
            throw new ArgumentNullException("queryable");
        }

        return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
    }

    public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenBy(keySelector);
        } else {
            return queryable.OrderBy(keySelector);
        }
    }

    public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenByDescending(keySelector);
        } else {
            return queryable.OrderByDescending(keySelector);
        }
    }
}

utilizzare la seguente riga sul DataContext per registrare l'attività SQL su DataContext sulla console, quindi è possibile visualizzare esattamente quali richieste del proprio linq richiedono dal database:

_db.Log = Console.Out

Le seguenti istruzioni LINQ:

var movies = from row in _db.Movies 
             orderby row.CategoryID, row.Name
             select row;

E

var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);

produrre il seguente SQL:

SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].CategoryID, [t0].[Name]

Considerando che, ripetendo un OrderBy in Linq, sembra invertire l'output SQL risultante:

var movies = from row in _db.Movies 
             orderby row.CategoryID
             orderby row.Name
             select row;

E

var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);

produrre il seguente SQL (Nome e CategoryId sono commutati):

SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID

Devi aggiungere la direzione dell'ordine subito dopo il nome della colonna:

$qb->orderBy('column1 ASC, column2 DESC');

Come hai notato, più chiamate a orderBy non si impilano , ma puoi effettuare più chiamate a addOrderBy :

$qb->addOrderBy('column1', 'ASC')
   ->addOrderBy('column2', 'DESC');




linq sql-order-by