我有两个表,电影和类别,我想先按类别ID,然后按名称获得一个有序列表。
电影表有三列ID、Name和CategoryID。类别表有两列ID和Name。
我尝试了下面的方法,但没有成功。
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
我有两个表,电影和类别,我想先按类别ID,然后按名称获得一个有序列表。
电影表有三列ID、Name和CategoryID。类别表有两列ID和Name。
我尝试了下面的方法,但没有成功。
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
当前回答
在DataContext上使用以下行将DataContext上的SQL活动记录到控制台,然后您可以确切地看到LINQ语句从数据库请求的内容:
_db.Log = Console.Out
以下LINQ语句:
var movies = from row in _db.Movies
orderby row.CategoryID, row.Name
select row;
AND
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;
AND
var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);
生成以下SQL(名称和CategoryId已切换):
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID
其他回答
这应该对您有用:
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;
[EDIT to address comment]要控制排序顺序,请使用关键字升序(这是默认值,因此不特别有用)或降序,如下所示:
var movies = from row in _db.Movies
orderby row.Category descending, row.Name
select row;
我已经创建了一些扩展方法(如下),因此您不必担心是否已经订购了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);
}
}
}
添加“新”:
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
这在我的箱子上管用。它确实返回了一些可以用来排序的东西。它返回了一个有两个值的对象。
类似,但不同于按组合列排序,如下所示。
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
使用LINQ至少还有一种方法可以做到这一点,尽管不是最简单的。您可以使用使用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());
如果需要将其中一项的排序切换为降序,只需在Compare()中切换x和y即可MovieComparer的方法。