J'ai deux tables, movies
et categories
, et je reçois une liste ordonnée par categoryID d'abord, puis par nom.
La table de film a trois colonnes ID, Nom et CategoryID. La table des catégories a 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 })
Cela devrait fonctionner pour vous:
var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
En utilisant LINQ, syntaxe de requête non-lambda, vous pouvez procéder comme suit:
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 n'est donc pas particulièrement utile) ou descending
, comme suit:
var movies = from row in _db.Movies
orderby row.Category descending, row.Name
select row;
Ajouter un 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.
Semblable 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 de votre DataContext pour consigner l'activité SQL sur le DataContext sur la console. Vous pourrez alors voir exactement ce que vos instructions linq demandent à la base de données:
_db.Log = Console.Out
Les déclarations 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 code 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 OrderBy dans Linq, il semble que la sortie SQL résultante soit inversée:
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 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 à partir 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);
}
}
}
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 une 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);
}
}
}
Ensuite, vous pouvez commander les films avec la syntaxe suivante:
var movies = _db.Movies.OrderBy(item => item, new MovieComparer());
Si vous avez besoin de changer l'ordre dans l'ordre décroissant pour l'un des éléments, il suffit de changer le x et le y à l'intérieur de la méthode Compare()
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();
else
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();