我有两个表,movies
和 categories
,我想先按 categoryID 然后按 Name 获取有序列表。
电影表有三列 ID、Name 和 CategoryID。类别表有两列 ID 和 Name。
我尝试了以下类似的方法,但没有奏效。
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;
[编辑地址注释] 要控制排序顺序,请使用关键字 ascending
(这是默认设置,因此不是特别有用)或 descending
,如下所示:
var movies = from row in _db.Movies
orderby row.Category descending, row.Name
select row;
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
。更正确的是from row in _db.Movies orderby row.Category descending orderby row.Name select row
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
。您提供的两个片段彼此等效,而不是 OP。
添新”:
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
这适用于我的盒子。它确实返回了一些可以用来排序的东西。它返回一个具有两个值的对象。
与按组合列排序类似,但不同,如下所示。
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
.OrderBy( m => new { m.CategoryID, m.Name })
和 .OrderBy( m => new { m.Name, m.CategoryID })
会产生相同的结果,而不是尊重预期的优先级。有时,它似乎会为您提供您想要的订单,这纯粹是出于巧合。此外,如果 CategoryID 是 int
,m.CategoryID.ToString() + m.Name
将产生不正确的排序。例如,id=123, name=5times 的东西会出现在 id=1234, name=something 之后而不是之前。在可能发生 int 比较的情况下进行字符串比较也不是低效的。
在您的 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(名称和 CategoryId 已切换):
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID
我创建了一些扩展方法(如下),因此您不必担心是否已经订购了 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);
}
}
}
使用 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());
如果您需要将其中一项的排序切换为降序,只需相应地在 MovieComparer
的 Compare()
方法中切换 x 和 y。
MovieComparer
;相反,您可以执行 _db.Movies.OrderBy(item => item, Comparer<Movie>.Create((x, y) => { if (x.CategoryId == y.CategoryId) { return x.Name.CompareTo(y.Name); } else { return x.CategoryId.CompareTo(y.CategoryId); } }));
。当然,如果您更喜欢将逻辑写成一个表达式,而不是 if
...else
,那么 lamda (x, y) => expr
可以更简单。
如果使用通用存储库
> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();
别的
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();
Var movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
2 次“orderBy”而不是Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
,为什么结果会不同?.ThenBy()
= 升序,.ThenByDescending()
= 降序!! (听起来合乎逻辑,对吧?)