Múltipla ordem por no LINQ

Eu tenho duas tabelas, movies e categories , e recebo uma lista ordenada por categoryID primeiro e depois por Name .

A tabela de filmes possui três colunas, ID, Nome e CategoryID . A tabela de categorias dois possui colunas, ID e nome .

Eu tentei algo como o seguinte, mas não funcionou.

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

Isso deve funcionar para você:

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

Usando não-lambda, a syntax de consulta LINQ, você pode fazer isso:

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

[EDIT para endereçar comentário] Para controlar a ordem de sorting, use as palavras-chave ascending (que é o padrão e, portanto, não é particularmente útil) ou descending , da seguinte forma:

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

Adicionar novo”:

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

Isso funciona na minha checkbox. Ele retorna algo que pode ser usado para classificar. Ele retorna um object com dois valores.

Similar, mas diferente de classificar por uma coluna combinada, como segue.

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

use a seguinte linha em seu DataContext para registrar a atividade SQL no DataContext para o console – então você pode ver exatamente o que suas instruções linq estão solicitando do database:

 _db.Log = Console.Out 

As seguintes instruções 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); 

produzir o seguinte SQL:

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

Considerando que, repetindo um OrderBy em Linq, parece inverter a saída SQL resultante:

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

produza o seguinte SQL (Name e CategoryId são comutados):

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

Há pelo menos mais uma maneira de fazer isso usando o LINQ, embora não seja o mais fácil. Você pode fazer isso usando o método OrberBy() que usa um IComparer . Primeiro você precisa implementar um IComparer para a class Movie assim:

 public class MovieComparer : IComparer { 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); } } } 

Então você pode encomendar os filmes com a seguinte syntax:

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

Se você precisar mudar a ordem para decrescente para um dos itens, mude o xey dentro do método Compare() do MovieComparer acordo.

Eu criei alguns methods de extensão (abaixo) para que você não precise se preocupar se um IQueryable já estiver ordenado ou não. Se você quiser encomendar por várias propriedades, faça o seguinte:

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

Isso é especialmente útil se você criar a ordenação dinamicamente, a partir de uma lista de propriedades para classificar.

 public static class IQueryableExtension { public static bool IsOrdered(this IQueryable queryable) { if(queryable == null) { throw new ArgumentNullException("queryable"); } return queryable.Expression.Type == typeof(IOrderedQueryable); } public static IQueryable SmartOrderBy(this IQueryable queryable, Expression> keySelector) { if(queryable.IsOrdered()) { var orderedQuery = queryable as IOrderedQueryable; return orderedQuery.ThenBy(keySelector); } else { return queryable.OrderBy(keySelector); } } public static IQueryable SmartOrderByDescending(this IQueryable queryable, Expression> keySelector) { if(queryable.IsOrdered()) { var orderedQuery = queryable as IOrderedQueryable; return orderedQuery.ThenByDescending(keySelector); } else { return queryable.OrderByDescending(keySelector); } } } 

Se usar repository genérico

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

outro

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