Saya memiliki dua tabel, movies
dan categories
, dan saya mendapatkan daftar yang diurutkan berdasarkan CategoryID pertama dan kemudian dengan Nama .
Tabel film memiliki tiga kolom ID, Nama dan CategoryID . Tabel kategori memiliki dua kolom ID dan Nama .
Saya mencoba sesuatu seperti yang berikut ini, tetapi tidak berhasil.
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
linq
sql-order-by
Sasha
sumber
sumber
Jawaban:
Ini seharusnya bekerja untuk Anda:
sumber
Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
jika saya menggunakanVar movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
2 kali "orderBy" mengapa hasilnya berbeda?ThenBy
?! ( Sunting: sepertinya diperkenalkan di .NET 4.0, yang menjelaskan bagaimana itu melewati saya tanpa disadari.)Menggunakan LINQ non-lambda, query-sintaks, Anda dapat melakukan ini:
[EDIT ke alamat komentar] Untuk mengontrol urutan, gunakan kata kunci
ascending
(yang merupakan default dan karenanya tidak terlalu berguna) ataudescending
, seperti:sumber
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
. Lebih tepatnya adalahfrom row in _db.Movies orderby row.Category descending orderby row.Name select row
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
. Dua cuplikan yang Anda berikan setara satu sama lain, bukan untuk OP.Tambah baru":
Itu bekerja di kotak saya. Itu mengembalikan sesuatu yang dapat digunakan untuk mengurutkan. Ini mengembalikan objek dengan dua nilai.
Serupa, tetapi berbeda dengan penyortiran menurut kolom gabungan, seperti berikut.
sumber
.OrderBy( m => new { m.CategoryID, m.Name })
dan.OrderBy( m => new { m.Name, m.CategoryID })
akan menghasilkan hasil yang sama daripada menghormati prioritas yang dimaksud. Kadang-kadang akan muncul memberi Anda pemesanan yang Anda inginkan murni secara kebetulan. Selain itum.CategoryID.ToString() + m.Name
akan menghasilkan pemesanan yang salah jika CategoryID adalahint
. Misalnya, sesuatu dengan id = 123, nama = 5 kali akan muncul setelah id = 1234, nama = sesuatu, bukan sebelumnya. Ini juga tidak efisien untuk melakukan perbandingan string di mana perbandingan int dapat terjadi.gunakan baris berikut pada DataContext Anda untuk mencatat aktivitas SQL pada DataContext ke konsol - maka Anda dapat melihat dengan tepat apa yang diminta oleh pernyataan LINQ Anda dari database:
Pernyataan LINQ berikut:
DAN
menghasilkan SQL berikut:
Sedangkan, mengulang OrderBy di Linq, tampaknya membalikkan hasil SQL yang dihasilkan:
DAN
menghasilkan SQL berikut (Nama dan CategoryId diaktifkan):
sumber
Saya telah membuat beberapa metode ekstensi (di bawah) sehingga Anda tidak perlu khawatir jika IQueryable sudah dipesan atau belum. Jika Anda ingin memesan oleh beberapa properti cukup lakukan sebagai berikut:
Ini sangat membantu jika Anda membuat urutan secara dinamis, dari daftar properti yang akan disortir.
sumber
nullable datetime
Setidaknya ada satu cara lagi untuk melakukan ini menggunakan LINQ, meskipun bukan yang termudah. Anda bisa melakukannya dengan menggunakan
OrberBy()
metode yang menggunakanIComparer
. Pertama, Anda perlu menerapkanIComparer
untukMovie
kelas seperti ini:Kemudian Anda dapat memesan film dengan sintaks berikut:
Jika Anda perlu mengganti urutan ke salah satu item, cukup ganti x dan y di dalam
Compare()
metode yangMovieComparer
sesuai.sumber
MovieComparer
sendiri; Anda bisa melakukannya_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); } }));
. Tentu saja, jika Anda lebih suka menulis logika sebagai satu ekspresi, daripadaif
...else
, maka lamda(x, y) => expr
bisa lebih sederhana.Jika menggunakan repositori generik
lain
sumber