在LINQ中有多个“order by”
我有两个表, movies
和categories
,我得到一个有序列表首先categoryID然后按名称 。
电影表有三列, ID,名称和CategoryID 。 类别表2有列, ID和名称 。
我尝试了类似下面的内容,但是没有奏效。
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
这应该为你工作:
Var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
使用非lambda,查询语法LINQ,你可以这样做:
var movies = from row in _db.Movies orderby row.Category, row.Name select row;
[编辑解决评论]要控制sorting顺序,使用关键字ascending
(这是默认的,因此不是特别有用)或descending
,如下所示:
var movies = from row in _db.Movies orderby row.Category descending, row.Name select row;
添新”:
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
这在我的箱子上工作。 它确实会返回可用于sorting的内容。 它返回一个有两个值的对象。
类似但不同于按组合列sorting,如下所示。
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
这应该工作。
在DataContext上使用以下行将DataContext上的SQL活动logging到控制台 – 然后就可以看到你的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
至less有一种使用LINQ的方法,尽pipe不是最简单的。 您可以通过使用使用IComparer
的OrberBy()
方法。 首先你需要像这样为Movie
类实现一个IComparer
:
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());
如果您需要将顺序切换为降序,则只需在MovieComparer
的Compare()
方法内切换x和y MovieComparer
。
我已经创build了一些扩展方法(下面),所以你不必担心,如果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);
如果您dynamic创buildsorting,那么这非常有用,可以从属性列表中sorting。
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); } } }