Question

J'ai deux tables, films et catégories , et je reçois une liste ordonnée par categoryID d'abord, puis par Nom .

La table de films comporte trois colonnes, ID, Nom et ID de catégorie . La table de catégories deux comporte 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 })
Était-ce utile?

La solution

Cela devrait fonctionner pour vous:

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

Autres conseils

En utilisant LINQ, une syntaxe de requête non lambda, vous pouvez le faire:

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 croissant (par défaut, donc pas particulièrement utile) ou décroissant , comme suit:

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

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 retourne 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))

utilisez la ligne suivante sur votre DataContext pour consigner l'activité SQL sur le DataContext sur la console. Vous pouvez alors voir exactement ce que vos instructions linq demandent à 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);

produit le code SQL suivant:

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

Alors que répéter un OrderBy dans Linq semble renverser la sortie SQL résultante:

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

produit le code SQL suivant (Name et CategoryId sont commutés):

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

J'ai créé des méthodes d'extension (ci-dessous) pour que vous n'ayez 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 la commande de manière dynamique, par exemple. dans 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);
        }
    }
}

Il existe au moins une autre façon de faire cela en utilisant LINQ, bien que ce ne soit pas la plus simple. Vous pouvez le faire en utilisant la méthode OrberBy () qui utilise un IComparer . Vous devez d'abord implémenter un IComparer pour la classe Movie 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);
        }
    }
}

Vous pouvez ensuite commander les films avec la syntaxe suivante:

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

Si vous avez besoin de passer en ordre décroissant pour l'un des éléments, il suffit de changer le x et le y à l'intérieur du Compare () . méthode du MovieComparer en conséquence.

Si vous utilisez un référentiel générique

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

sinon

> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top