Pertimbangkan metode ekstensi IEnumerable SingleOrDefault()
danFirstOrDefault()
Dokumen MSDN itu SingleOrDefault
:
Mengembalikan satu-satunya elemen urutan, atau nilai default jika urutannya kosong; Metode ini melempar pengecualian jika ada lebih dari satu elemen dalam urutan.
sedangkan FirstOrDefault
dari MSDN (mungkin saat menggunakan OrderBy()
atau OrderByDescending()
atau tidak sama sekali),
Mengembalikan elemen pertama dari suatu urutan
Pertimbangkan beberapa contoh kueri, tidak selalu jelas kapan harus menggunakan kedua metode ini:
var someCust = db.Customers
.SingleOrDefault(c=>c.ID == 5); //unlikely(?) to be more than one, but technically COULD BE
var bobbyCust = db.Customers
.FirstOrDefault(c=>c.FirstName == "Bobby"); //clearly could be one or many, so use First?
var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or does it matter?
Pertanyaan
Konvensi apa yang Anda ikuti atau sarankan ketika memutuskan untuk menggunakan SingleOrDefault()
dan FirstOrDefault()
dalam pertanyaan LINQ Anda?
sumber
Jika set hasil Anda mengembalikan 0 catatan:
SingleOrDefault
mengembalikan nilai default untuk tipe (mis. default untuk int adalah 0)FirstOrDefault
mengembalikan nilai default untuk tipe tersebutJika Anda menghasilkan set, kembalikan 1 catatan:
SingleOrDefault
mengembalikan catatan ituFirstOrDefault
mengembalikan catatan ituJika set hasil Anda mengembalikan banyak catatan:
SingleOrDefault
melempar pengecualianFirstOrDefault
mengembalikan catatan pertamaKesimpulan:
Jika Anda ingin pengecualian dilemparkan jika set hasil berisi banyak catatan, gunakan
SingleOrDefault
.Jika Anda selalu ingin 1 catatan apa pun yang berisi hasil set, gunakan
FirstOrDefault
sumber
FirstOrDefault
dikembalikan catatan pertama berarti catatan baru (terakhir) / catatan lama (pertama)? bisakah Anda mengklarifikasi saya?Ada
antara keduanya.
Perbedaan semantik:
FirstOrDefault
mengembalikan item pertama yang berpotensi banyak (atau default jika tidak ada).SingleOrDefault
mengasumsikan bahwa ada satu item dan mengembalikannya (atau default jika tidak ada). Beberapa item merupakan pelanggaran kontrak, pengecualian dilemparkan.Perbedaan Kinerja
FirstOrDefault
biasanya lebih cepat, iterates sampai ia menemukan elemen dan hanya perlu mengulangi seluruh enumerable ketika tidak menemukannya. Dalam banyak kasus, ada kemungkinan besar untuk menemukan item.SingleOrDefault
perlu memeriksa apakah hanya ada satu elemen dan karena itu selalu iterates seluruh enumerable. Lebih tepatnya, itu berulang sampai menemukan elemen kedua dan melempar pengecualian. Tetapi dalam kebanyakan kasus, tidak ada elemen kedua.Kesimpulan
Gunakan
FirstOrDefault
jika Anda tidak peduli berapa banyak item yang ada atau ketika Anda tidak mampu memeriksa keunikan (misalnya dalam koleksi yang sangat besar). Saat Anda memeriksa keunikan dalam menambahkan item ke koleksi, mungkin terlalu mahal untuk memeriksanya lagi saat mencari item tersebut.Gunakan
SingleOrDefault
jika Anda tidak perlu terlalu memperhatikan kinerja dan ingin memastikan bahwa asumsi satu item jelas untuk pembaca dan diperiksa saat runtime.Dalam praktiknya, Anda menggunakan
First
/FirstOrDefault
sering bahkan dalam kasus ketika Anda mengasumsikan satu item, untuk meningkatkan kinerja. Anda harus tetap ingat bahwaSingle
/ sayaSingleOrDefault
dapat meningkatkan keterbacaan (karena itu menyatakan asumsi satu item) dan stabilitas (karena memeriksa itu) dan menggunakannya dengan tepat.sumber
SingleOrDefault
banyak objek ketika menggunakan Linq untuk Objects, tetapi tidakSingleOrDefault
harus mengulangi paling banyak 2 item jika Linq berbicara ke database misalnya? Hanya ingin tahu ..Enumerable
.Tidak ada yang menyebutkan bahwa FirstOrDefault diterjemahkan dalam SQL tidak merekam TOP 1, dan SingleOrDefault melakukan TOP 2, karena perlu tahu apakah ada lebih dari 1 catatan.
sumber
FirstOrDefault()
menambahkanLIMIT 0,1
sambilSingleOrDefault()
menambahkan apa-apa.Untuk LINQ -> SQL:
SingleOrDefault
Masalah Pertama atau Kesalahan
sumber
Saya menggunakan
SingleOrDefault
dalam situasi di mana logika saya menentukan bahwa akan menjadi nol atau satu hasil. Jika ada lebih banyak, ini adalah situasi kesalahan, yang sangat membantu.sumber
SingleOrDefault: Anda mengatakan bahwa "Paling banyak" ada satu item yang cocok dengan kueri atau default FirstOrDefault: Anda mengatakan bahwa ada "Setidaknya" satu item yang cocok dengan kueri atau default
Katakan dengan keras waktu berikutnya Anda harus memilih dan Anda akan memilih dengan bijak. :)
sumber
FirstOrDefault. More correctly:
FirstOrDefault` = yang dapat diterima sepenuhnya = Sejumlah hasil tetapi saya hanya peduli pada yang pertama, mungkin juga tidak ada hasil.SingleOrDefault
= Ada 1 atau 0 hasil, jika ada lebih banyak itu berarti ada kesalahan di suatu tempat.First
= Setidaknya ada satu hasil, dan saya menginginkannya.Single
= Ada 1 hasil, tidak lebih, tidak kurang, dan saya ingin yang itu.Dalam kasus Anda, saya akan menggunakan yang berikut:
pilih dengan ID == 5: boleh saja menggunakan SingleOrDefault di sini, karena Anda mengharapkan satu entitas [atau tidak sama sekali], jika Anda mendapatkan lebih dari satu entitas dengan ID 5, ada sesuatu yang salah dan tentu saja pengecualian layak.
ketika mencari orang yang nama depannya sama dengan "Bobby", mungkin ada lebih dari satu (sangat mungkin saya akan berpikir), jadi Anda tidak boleh menggunakan Tunggal atau Pertama, cukup pilih dengan Operasi di mana (jika "Bobby" mengembalikan terlalu banyak entitas, pengguna harus mempersempit pencariannya atau memilih salah satu hasil yang dikembalikan)
urutan berdasarkan tanggal pembuatan juga harus dilakukan dengan Operasi di mana (tidak mungkin hanya memiliki satu entitas, pengurutan tidak akan banyak berguna;) namun ini menyiratkan Anda ingin SEMUA entitas diurutkan - jika Anda ingin SATU saja, gunakan FirstOrDefault, Single akan melempar setiap kali jika Anda mendapatkan lebih dari satu entitas.
sumber
Keduanya adalah operator elemen dan mereka digunakan untuk memilih elemen tunggal dari suatu urutan. Tetapi ada perbedaan kecil di antara mereka. Operator SingleOrDefault () akan melempar eksepsi jika lebih dari satu elemen puas dengan kondisi di mana FirstOrDefault () tidak akan melempar eksepsi untuk hal yang sama. Inilah contohnya.
sumber
Dalam contoh terakhir Anda:
Ya itu. Jika Anda mencoba menggunakan
SingleOrDefault()
dan hasil kueri lebih dari catatan Anda akan mendapatkan dan pengecualian. Satu-satunya waktu Anda dapat menggunakan dengan amanSingleOrDefault()
adalah ketika Anda mengharapkan hanya 1 dan hanya 1 hasil ...sumber
Jadi seperti yang saya mengerti sekarang,
SingleOrDefault
akan lebih baik jika Anda meminta data yang dijamin unik yaitu ditegakkan oleh batasan DB seperti kunci primer.Atau ada cara yang lebih baik untuk menanyakan kunci utama.
Dengan asumsi TableAcc saya miliki
dan saya ingin meminta
AccountNumber 987654
, saya gunakansumber
Menurut pendapat saya
FirstOrDefault
terlalu sering digunakan. Dalam sebagian besar kasus saat Anda memfilter data, Anda akan diharapkan untuk mendapatkan kembali kumpulan elemen yang cocok dengan kondisi logis atau elemen unik tunggal dengan pengidentifikasi unik - seperti pengguna, buku, posting dll ... Itu mengapa kita bahkan bisa mengatakan bahwa ituFirstOrDefault()
adalah bau kode bukan karena ada sesuatu yang salah dengan itu tetapi karena terlalu sering digunakan. Posting blog ini mengeksplorasi topik secara rinci. IMO sebagian besar kaliSingleOrDefault()
adalah alternatif yang jauh lebih baik jadi waspadai kesalahan ini dan pastikan Anda menggunakan metode yang paling tepat yang dengan jelas mewakili kontrak dan harapan Anda.sumber
Satu hal yang terlewatkan dalam tanggapan ....
Jika ada beberapa hasil, FirstOrDefault tanpa perintah oleh dapat membawa kembali hasil yang berbeda berdasarkan strategi indeks yang pernah digunakan oleh server.
Secara pribadi saya tidak tahan melihat FirstOrDefault dalam kode karena bagi saya dikatakan pengembang tidak peduli dengan hasilnya. Dengan pesanan meskipun itu bisa berguna sebagai cara menegakkan yang terbaru / paling awal. Saya harus memperbaiki banyak masalah yang disebabkan oleh pengembang yang ceroboh menggunakan FirstOrDefault.
sumber
Saya bertanya kepada Google untuk penggunaan berbagai metode di GitHub. Ini dilakukan dengan menjalankan kueri pencarian Google untuk setiap metode dan membatasi kueri ke domain github.com dan ekstensi file .cs dengan menggunakan kueri "site: file github.com: cs ..."
Tampaknya metode First * lebih umum digunakan daripada metode Single *.
sumber
Saya tidak mengerti mengapa Anda menggunakan
FirstOrDefault(x=> x.ID == key)
saat ini dapat mengambil hasil lebih cepat jika Anda gunakanFind(key)
. Jika Anda bertanya dengan kunci utama tabel, aturan praktisnya adalah untuk selalu menggunakanFind(key)
.FirstOrDefault
harus digunakan untuk hal-hal predikat seperti(x=> x.Username == username)
dll.ini tidak layak downvote karena judul pertanyaan tidak spesifik untuk LINQ pada DB atau LINQ untuk daftar / IEnumerable dll
sumber
Find()
?