Saya mencoba mengurutkan daftar produk berdasarkan harganya.
Kumpulan hasil perlu mencantumkan produk menurut harga dari rendah ke tinggi menurut kolom LowestPrice
. Namun, kolom ini tidak dapat diisi.
Saya dapat mengurutkan daftar dalam urutan seperti ini:
var products = from p in _context.Products
where p.ProductTypeId == 1
orderby p.LowestPrice.HasValue descending
orderby p.LowestPrice descending
select p;
// returns: 102, 101, 100, null, null
Namun saya tidak tahu bagaimana mengurutkan ini dalam urutan naik.
// i'd like: 100, 101, 102, null, null
orderby p.LowestPrice ?? Int.MaxValue;
adalah cara yang sederhana.OrderByDescending, ThenBy
lebih jelas.orderby
, dan dilacak samping mencarinya :)Jawaban:
Coba letakkan kedua kolom dalam urutan yang sama.
orderby p.LowestPrice.HasValue descending, p.LowestPrice
Jika tidak, setiap orderby adalah operasi terpisah pada koleksi yang menyusun ulang setiap waktu.
Ini harus mengurutkan yang memiliki nilai terlebih dahulu, "lalu" urutan nilainya.
sumber
orderby p.LowestPrice == null, p.LowestPrice ascending
Harapan membantu seseorang.Sangat membantu untuk memahami sintaks kueri LINQ dan bagaimana itu diterjemahkan ke panggilan metode LINQ.
Ternyata begitu
var products = from p in _context.Products where p.ProductTypeId == 1 orderby p.LowestPrice.HasValue descending orderby p.LowestPrice descending select p;
akan diterjemahkan oleh kompilator ke
var products = _context.Products .Where(p => p.ProductTypeId == 1) .OrderByDescending(p => p.LowestPrice.HasValue) .OrderByDescending(p => p.LowestPrice) .Select(p => p);
Ini jelas bukan yang Anda inginkan. Ini macam oleh
Product.LowestPrice.HasValue
didescending
urutan dan kemudian kembali macam seluruh koleksi olehProduct.LowestPrice
didescending
urutan.Apa yang kamu inginkan adalah
var products = _context.Products .Where(p => p.ProductTypeId == 1) .OrderByDescending(p => p.LowestPrice.HasValue) .ThenBy(p => p.LowestPrice) .Select(p => p);
yang bisa Anda peroleh menggunakan sintaks kueri
var products = from p in _context.Products where p.ProductTypeId == 1 orderby p.LowestPrice.HasValue descending, p.LowestPrice select p;
Untuk mengetahui detail terjemahan dari sintaks kueri ke panggilan metode, lihat spesifikasi bahasa. Sungguh. Membacanya.
sumber
Solusi untuk nilai string sangat aneh:
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
Satu-satunya alasan yang berhasil adalah karena ekspresi pertama,
OrderBy()
,, mengurutkanbool
nilai:true
/false
.false
hasilnya pergi dulu diikuti olehtrue
hasilnya (nullables) danThenBy()
urutkan nilai bukan null menurut abjad.e.g.: [null, "coconut", null, "apple", "strawberry"] First sort: ["coconut", "apple", "strawberry", null, null] Second sort: ["apple", "coconut", "strawberry", null, null]
Jadi, saya lebih suka melakukan sesuatu yang lebih mudah dibaca seperti ini:
.OrderBy(f => f.SomeString ?? "z")
Jika
SomeString
nol, itu akan diganti dengan"z"
dan kemudian mengurutkan semuanya menurut abjad.CATATAN: Ini bukan solusi pamungkas karena
"z"
lebih dulu daripada nilai-z sepertizebra
.UPDATE 9/6/2016 - Tentang komentar @jornhd, ini benar-benar solusi yang bagus, tetapi masih sedikit rumit, jadi saya akan merekomendasikan untuk membungkusnya dalam kelas Ekstensi, seperti ini:
public static class MyExtensions { public static IOrderedEnumerable<T> NullableOrderBy<T>(this IEnumerable<T> list, Func<T, string> keySelector) { return list.OrderBy(v => keySelector(v) != null ? 0 : 1).ThenBy(keySelector); } }
Dan gunakan sederhana seperti:
var sortedList = list.NullableOrderBy(f => f.SomeString);
sumber
Saya punya pilihan lain dalam situasi ini. Daftar saya adalah objList, dan saya harus memesan tetapi null harus di akhir. keputusanku:
var newList = objList.Where(m=>m.Column != null) .OrderBy(m => m.Column) .Concat(objList.where(m=>m.Column == null));
sumber
Saya mencoba menemukan solusi LINQ untuk ini tetapi tidak dapat menyelesaikannya dari jawaban di sini.
Jawaban terakhir saya adalah:
sumber
keputusanku:
Array = _context.Products.OrderByDescending(p => p.Val ?? float.MinValue)
sumber
Inilah yang saya dapatkan karena saya menggunakan metode ekstensi dan juga item saya adalah string, jadi tidak
.HasValue
:.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
Ini bekerja dengan objek LINQ 2 di memori. Saya tidak mengujinya dengan EF atau DB ORM.
sumber
Di bawah ini adalah metode ekstensi untuk memeriksa null jika Anda ingin mengurutkan pada properti turunan dari keySelector.
public static IOrderedEnumerable<T> NullableOrderBy<T>(this IEnumerable<T> list, Func<T, object> parentKeySelector, Func<T, object> childKeySelector) { return list.OrderBy(v => parentKeySelector(v) != null ? 0 : 1).ThenBy(childKeySelector); }
Dan gunakan sederhana seperti:
var sortedList = list.NullableOrderBy(x => x.someObject, y => y.someObject?.someProperty);
sumber
Berikut cara lain:
//Acsending case "SUP_APPROVED_IND": qry = qry.OrderBy(r => r.SUP_APPROVED_IND.Trim() == null). ThenBy(r => r.SUP_APPROVED_IND); break; //…. //Descending case "SUP_APPROVED_IND": qry = qry.OrderBy(r => r.SUP_APPROVED_IND.Trim() == null). ThenByDescending(r => r.SUP_APPROVED_IND); break;
SUP_APPROVED_IND is char(1) in Oracle db.
Catatan yang
r.SUP_APPROVED_IND.Trim() == null
diperlakukan sepertitrim(SUP_APPROVED_IND) is null
di Oracle db.Lihat ini untuk detailnya: Bagaimana saya bisa meminta nilai null dalam kerangka entitas?
sumber
Opsi Lain (berguna untuk skenario kami):
Kami memiliki Tabel Pengguna, menyimpan
ADName, LastName, FirstName
Kami mengubah skema tabel dan menambahkan Kolom "SortIndex", yang mendefinisikan beberapa grup penyortiran. (Kami menyisakan jarak 5, jadi kami bisa memasukkan grup nanti)
ID | ADName | First Name | LastName | SortIndex 0 No Selection null null | 0 1 AD\jon Jon Doe | 5 3 AD\Support null null | 10 4 AD\Accounting null null | 10 5 AD\ama Amanda Whatever | 5
Sekarang, berdasarkan kueri:
SELECT * FROM User order by SortIndex, LastName, FirstName, AdName;
dalam Metode Ekspresi:
yang menghasilkan hasil yang diharapkan:
ID | ADName | First Name | LastName | SortIndex 0 No Selection null null | 0 5 AD\ama Amanda Whatever | 5 1 AD\jon Jon Doe | 5 4 AD\Accounting null null | 10 3 AD\Support null null | 10
sumber