Question Multiple "ordre par" dans LINQ


J'ai deux tables, movies et categories, et je reçois une liste ordonnée par categoryID d'abord, puis par prénom.

La table de film a trois colonnes, ID, nom et ID de catégorie. La table de catégorie deux a des colonnes, ID et nom.

J'ai essayé quelque chose comme ce qui suit, mais cela n'a pas fonctionné.

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

1380
2017-11-18 13:34


origine


Réponses:


Cela devrait fonctionner pour vous:

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

2524
2017-11-18 13:41



En utilisant LINQ, syntaxe de requête non-lambda, vous pouvez faire ceci:

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

[EDIT to address comment] Pour contrôler l'ordre de tri, utilisez les mots-clés ascending (qui est la valeur par défaut et donc pas particulièrement utile) ou descending, ainsi:

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

550
2017-09-30 14:49



Ajouter "nouveau":

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

Cela fonctionne sur ma boîte. Il retourne quelque chose qui peut être utilisé pour trier. Il renvoie un objet avec deux valeurs.

Similaire, mais différent du tri par colonne combinée, comme suit.

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

67
2018-06-22 14:27



utilisez la ligne suivante sur votre DataContext pour enregistrer l'activité SQL sur le DataContext sur la console - vous pouvez alors voir exactement ce que vos instructions linq demandent de la base de données:

_db.Log = Console.Out

Les instructions LINQ suivantes:

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

ET

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

produire le SQL suivant:

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

Considérant que, en répétant un OrderBy dans Linq, semble inverser la sortie SQL qui en résulte:

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

ET

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

produire le code SQL suivant (Name et CategoryId sont activés):

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

18
2018-02-18 21:03



Il y a au moins une autre façon de le faire en utilisant LINQ, bien que ce ne soit pas le plus simple. Vous pouvez le faire en utilisant le OrberBy() méthode qui utilise un IComparer. D'abord, vous devez mettre en œuvre un IComparer pour le Movie classe comme ceci:

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);
        }
    }
}

Ensuite, vous pouvez commander les films avec la syntaxe suivante:

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

Si vous avez besoin de passer la commande à la descente pour l'un des éléments, il suffit de basculer le x et le y dans le Compare()  méthode de MovieComparer en conséquence.


12
2018-04-03 14:07



J'ai créé quelques méthodes d'extension (ci-dessous) donc vous n'avez pas à vous inquiéter si un IQueryable est déjà commandé ou non. Si vous souhaitez commander par plusieurs propriétés, procédez comme suit:

// 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);

Ceci est particulièrement utile si vous créez dynamiquement la commande, f.e. d'une liste de propriétés à trier.

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);
        }
    }
}

11
2018-06-08 14:49



Si utiliser le référentiel générique

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

autre

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

0
2017-07-17 14:29