Wiele "order by" w LINQ

Mam dwie tabele, movies i categories, i otrzymuję uporządkowaną listę według categoryID najpierw, a następnie według Nazwa .

Tabela filmu zawiera trzy kolumny ID, Name i CategoryID . Tabela kategorii zawiera dwie kolumny ID i Nazwa .

Próbowałem czegoś takiego jak poniżej, ale nie zadziałało.
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
Author: Sudhir Dehade, 2008-11-18

7 answers

To powinno działać dla ciebie:

var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
 2916
Author: Nathan W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 14:53:22

Używając Nie-lambda, query-syntax LINQ, możesz to zrobić:

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

[EDIT to address comment] aby kontrolować kolejność sortowania, użyj słów kluczowych ascending (które są domyślne i dlatego nie są szczególnie przydatne) lub descending, Jak Tak:

var movies = from row in _db.Movies 
             orderby row.Category descending, row.Name
             select row;
 603
Author: Scott Stafford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 20:57:43

Dodaj"nowy":

var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
To działa na moim pudełku. Zwraca coś, co można wykorzystać do sortowania. Zwraca obiekt z dwiema wartościami.

Podobne, ale różne do sortowania według połączonych kolumn, jak poniżej.

var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
 77
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 12:17:42

Użyj następującej linii na DataContext, aby zalogować aktywność SQL na DataContext do konsoli - wtedy możesz zobaczyć dokładnie to, czego żądają twoje instrukcje linq z bazy danych:

_db.Log = Console.Out

Następujące wypowiedzi LINQ:

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

I

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

Wygeneruj następujący SQL:

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

Podczas gdy powtarzanie OrderBy w Linq, wydaje się odwracać wynikowe wyjście SQL:

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

I

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

Produkuj następujący SQL (Nazwa i Kategorie są przełączane):

SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID
 32
Author: Oliver Slay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 12:08:32

Stworzyłem kilka metod rozszerzeń (poniżej), więc nie musisz się martwić, czy IQueryable jest już zamówiony, czy nie. Jeśli chcesz zamówić przez wiele właściwości po prostu zrób to w następujący sposób:

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

Jest to szczególnie pomocne w przypadku dynamicznego tworzenia kolejności, np. z listy właściwości do sortowania.

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);
        }
    }
}
 26
Author: sjkm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 12:17:17

Jest co najmniej jeden sposób, aby to zrobić za pomocą LINQ, chociaż nie jest to najłatwiejsze. Możesz to zrobić za pomocą metody OrberBy(), która używa IComparer. Najpierw musisz zaimplementuj IComparer dla klasy Movie w ten sposób:

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

Następnie możesz zamówić filmy z następującą składnią:

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

Jeśli chcesz przełączyć kolejność na malejącą dla jednego z elementów po prostu przełącz x i y wewnątrz Compare() metoda MovieComparer odpowiednio.

 17
Author: prudentcoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-03 14:12:32

If use generic repository

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

Else

> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();
 4
Author: Saint-martin Guillaume,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 14:35:11