との2つのテーブルがmovies
ありcategories
、最初にcategoryID、次にNameで順序付けされたリストを取得します。
ムービーテーブルには、ID、Name、CategoryIDの 3つの列があります。カテゴリテーブルには、IDとNameの 2つの列があります。
次のようなものを試しましたが、うまくいきませんでした。
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
との2つのテーブルがmovies
ありcategories
、最初にcategoryID、次にNameで順序付けされたリストを取得します。
ムービーテーブルには、ID、Name、CategoryIDの 3つの列があります。カテゴリテーブルには、IDとNameの 2つの列があります。
次のようなものを試しましたが、うまくいきませんでした。
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
回答:
これはあなたのために働くはずです:
var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
使用する代わりに 、 Var movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
なぜ結果が異なるのですか?
ThenBy
一体どうして私は知らないうちにずっとこの世に行ってきたのですか?(編集:それが.NET 4.0で導入されたように見えます。それはそれが気付かれずに私をすり抜けてしまった方法を説明しています。)
非ラムダ、クエリ構文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)
。指定する2つのスニペットは、OPではなく互いに同等です。
新しく追加する":
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
それは私の箱で動作します。ソートに使用できるものを返します。2つの値を持つオブジェクトを返します。
次のように、結合された列による並べ替えと似ていますが異なります。
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 })
ています。たまたま、純粋に必要な順序になっているように見えることがあります。さらにm.CategoryID.ToString() + m.Name
、CategoryIDがの場合、誤った順序が生成されint
ます。たとえば、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を生成します(名前とカテゴリIDが切り替えられます)。
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);
}
}
}
nullable datetime
最も簡単ではありませんが、LINQを使用してこれを行う方法が少なくとも1つあります。を使用する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());
アイテムの1つについて降順に順序を切り替える必要がある場合Compare()
は、MovieComparer
それに応じてのメソッド内で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
... ではなく1つの式として記述したい場合else
は、ラムダ(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();