LINQ中的多个“order by”

时间:2008-11-18 13:34:12

标签: linq sql-order-by

我有两个表格moviescategories,我首先按 categoryID 获取有序列表,然后按名称获得。

影片表有三列, ID,名称和类别ID 。 类别表格2包含列 ID和名称

我尝试了类似下面的内容,但它没有用。

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

8 个答案:

答案 0 :(得分:2674)

这应该适合你:

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

答案 1 :(得分:575)

使用非lambda查询语法LINQ,您可以这样做:

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

[用于解决评论的编辑]要控制排序顺序,请使用关键字ascending(这是默认值,因此不是特别有用)或descending,如下所示:

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

答案 2 :(得分:71)

添加“新”:

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

这适用于我的盒子。它确实返回了可用于排序的东西。它返回一个具有两个值的对象。

类似,但与按组合列排序不同,如下所示。

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

答案 3 :(得分:25)

在DataContext上使用以下行将DataContext上的SQL活动记录到控制台 - 然后您可以准确地看到您的linq语句从数据库请求的内容:

_db.Log = Console.Out

以下LINQ语句:

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

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

生成以下SQL:

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

然而,在Linq中重复OrderBy似乎会反转生成的SQL输出:

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

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

生成以下SQL(Name和CategoryId被切换):

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

答案 4 :(得分:18)

我已经创建了一些扩展方法(如下所示),因此您不必担心是否已经订购了IQueryable。如果您想按多个属性订购,请按以下步骤操作:

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

如果您动态创建排序,这将特别有用,例如。从要排序的属性列表中。

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

答案 5 :(得分:13)

使用LINQ至少还有一种方法可以做到这一点,尽管不是最简单的方法。 您可以使用OrberBy()使用IComparer方法来执行此操作。首先你需要 为IComparer类实现Movie,如下所示:

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

然后您可以使用以下语法订购电影:

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

如果您需要将其中一个项目的顺序切换为降序,只需在Compare()内切换x和y即可 因此MovieComparer的方法。

答案 6 :(得分:1)

如果使用通用存储库

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

其他

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

答案 7 :(得分:0)

您可以通过连接列对项目进行排序:

var sortedMovies = _db.Movies.OrderBy(item => string.Concat(item.CategoryID, item.Name));