movies
とcategories
という2つのテーブルがあり、最初に categoryID で、次に Name で順序付けされたリストを取得します。
Movieテーブルには、3つの列、 ID、Name、および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)
非ラムダのクエリ構文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;
新しく追加する":
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
それは私の箱の上で動作します。ソートに使用できるものを返します。 2つの値を持つオブジェクトを返します。
次のように、結合列によるソートと似ていますが、異なります。
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + 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;
そして
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
私はいくつかの拡張メソッドを作成しました(下記)ので、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を使用してこれを行う方法が少なくとももう1つあります。 IComparer
を使用するOrberBy()
メソッドを使用してそれを行うことができます。まず、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());
いずれかの項目で順序を降順に切り替える必要がある場合は、それに応じてMovieComparer
のCompare()
メソッド内でxとyを切り替えるだけです。
汎用リポジトリを使用している場合
> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();
else
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();