J'ai deux tables, movies
et categories
, et j'obtiens une liste ordonnée par categoryID d' abord, puis par nom .
La table de film a trois colonnes ID, Name et CategoryID . Le tableau des catégories comporte deux 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 })
linq
sql-order-by
Sasha
la source
la source
Réponses:
Cela devrait fonctionner pour vous:
la source
Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
si j'utiliseVar movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
2 fois "orderBy" pourquoi le résultat est-il différent?ThenBy
?! ( Edit: on dirait qu'il a été introduit dans .NET 4.0, ce qui explique comment il est passé devant moi sans être remarqué.)En utilisant LINQ non-lambda, à syntaxe de requête, vous pouvez faire ceci:
[MODIFIER pour répondre au commentaire] Pour contrôler l'ordre de tri, utilisez les mots-clés
ascending
(qui sont par défaut et donc pas particulièrement utiles) oudescending
, comme ceci:la source
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
. Plus correct estfrom row in _db.Movies orderby row.Category descending orderby row.Name select row
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
. Les deux extraits que vous fournissez sont équivalents l'un à l'autre, pas aux PO.Ajouter "nouveau":
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.
la source
.OrderBy( m => new { m.CategoryID, m.Name })
et.OrderBy( m => new { m.Name, m.CategoryID })
produira les mêmes résultats plutôt que sur la priorité voulue. Il semblera parfois vous donner l'ordre que vous souhaitez uniquement par coïncidence. De plusm.CategoryID.ToString() + m.Name
, des commandes incorrectes seront produites si CategoryID est unint
. Par exemple, quelque chose avec id = 123, nom = 5 fois apparaîtra après id = 1234, nom = quelque chose au lieu d'avant. Il n'est pas non plus inefficace de faire des comparaisons de chaînes où des comparaisons int peuvent se produire.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:
Les instructions LINQ suivantes:
ET
produire le SQL suivant:
Alors que la répétition d'un OrderBy dans Linq semble inverser la sortie SQL résultante:
ET
produire le SQL suivant (le nom et le CategoryId sont commutés):
la source
J'ai créé quelques méthodes d'extension (ci-dessous) afin que vous n'ayez pas à vous inquiéter si un IQueryable est déjà commandé ou non. Si vous souhaitez classer par plusieurs propriétés, procédez comme suit:
Cela est particulièrement utile si vous créez l'ordre de manière dynamique, par exemple à partir d'une liste de propriétés à trier.
la source
nullable datetime
Il existe au moins une autre façon de procéder à l'aide de LINQ, mais ce n'est pas la plus simple. Vous pouvez le faire en utilisant la
OrberBy()
méthode qui utilise unIComparer
. Vous devez d'abord implémenter unIComparer
pour laMovie
classe comme ceci:Ensuite, vous pouvez commander les films avec la syntaxe suivante:
Si vous avez besoin de changer l'ordre en descendant pour l'un des éléments, il suffit de changer les x et y à l'intérieur de la
Compare()
méthode du enMovieComparer
conséquence.la source
MovieComparer
vous - même; à la place, vous pouvez le faire_db.Movies.OrderBy(item => item, Comparer<Movie>.Create((x, y) => { if (x.CategoryId == y.CategoryId) { return x.Name.CompareTo(y.Name); } else { return x.CategoryId.CompareTo(y.CategoryId); } }));
. Bien sûr, si vous préférez écrire la logique comme une seule expression, au lieu deif
...else
, alors le lamda(x, y) => expr
peut être plus simple.Si utiliser un référentiel générique
autre
la source