Kerangka Kerja Entitas 4 Tunggal () vs Pertama () vs FirstOrDefault ()

119

Saya mengalami kesulitan menemukan perbandingan berbagai cara untuk meminta satu item, dan kapan harus menggunakannya.

Adakah yang punya link yang membandingkan semua ini, atau penjelasan singkat tentang mengapa Anda menggunakan salah satunya? Apakah masih ada lebih banyak operator yang tidak saya sadari?

Terima kasih.

asfsadf.dll
sumber

Jawaban:

205

Berikut ini ikhtisar dari berbagai metode:

  • Temukan () - ketika Anda ingin mendapatkan item dengan kunci utama. Ini akan mengembalikan null jika tidak dapat menemukan item. Ini akan melihat dalam konteks sebelum pergi ke database (seperti yang ditunjukkan oleh Yaron di komentar) yang dapat menjadi faktor efisiensi penting jika Anda perlu mendapatkan entitas yang sama beberapa kali sementara konteks yang sama masih aktif.

  • Single () - ketika Anda mengharapkan tepat satu item dikembalikan oleh kueri. Ini akan memunculkan pengecualian jika kueri tidak mengembalikan tepat satu item.

  • SingleOrDefault () - saat Anda mengharapkan nol atau satu item dikembalikan oleh kueri (yaitu Anda tidak yakin apakah item dengan kunci tertentu ada). Ini akan memunculkan pengecualian jika kueri tidak mengembalikan nol atau satu item.

  • First () - ketika Anda mengharapkan satu atau beberapa item dikembalikan oleh kueri tetapi Anda hanya ingin mengakses item pertama dalam kode Anda (pengurutan bisa menjadi penting dalam kueri di sini). Ini akan memunculkan pengecualian jika kueri tidak mengembalikan setidaknya satu item.

  • FirstOrDefault () - ketika Anda mengharapkan nol atau lebih item untuk dikembalikan oleh kueri tetapi Anda hanya ingin mengakses item pertama dalam kode Anda (yaitu Anda tidak yakin apakah item dengan kunci yang diberikan ada)

Steve Willcock
sumber
1
Itu tergantung skenario. Jika Anda tahu bahwa Anda harus selalu mendapatkan satu record kembali dari db, tidak lebih, tidak kurang, untuk query tertentu maka Single () adalah yang 'tepat' untuk digunakan. Dalam situasi lain, situasi lain mungkin lebih tepat. Dalam versi EF sebelumnya, kami terbatas pada First () dan FirstOrDefault () yang bekerja untuk skenario di mana Anda mengharapkan satu catatan tetapi mereka tidak akan memperingatkan Anda jika Anda benar-benar mendapatkan lebih dari satu catatan itu kembali yang mungkin penting tergantung pada situasi.
Steve Willcock
1
Terima kasih. Saya tidak dapat melihat diri saya membutuhkan First () lagi, di mana Single () tidak akan lebih baik. Jika saya kurang padat, saya yakin saya bisa menghargai / memahami kapan harus menggunakan First ().
asfsadf
1
First () paling masuk akal dalam kasus di mana Anda ingin mengambil hanya objek dengan yang tertinggi atau terendah dari yang Anda pesan. Misalnya, temukan saya obral dengan nilai total tertinggi. Sales.OrderByDescending(s => s.TotalValue).First();
Mike Chamberlain
5
Semua komentar terlihat perbedaan penting. Find () adalah satu-satunya metode yang mencari konteks sebelum menekan db.
Yaron Levi
5
Poin lain adalah saat membuat kueri database sql, Singleatau SingleOrDefaultakan meminta 2 catatan (batas 2) sementara Firstatau FirstOrDefaultakan meminta 1 (batas 1).
Bart Calixto
22

Saya selalu cenderung menggunakan FirstOrDefault. Jika Anda benar-benar ingin pilih-pilih dengan performa, Anda harus menggunakan FirstOrDefaultEF. Di bawah sampul SingleOrDefaultmenggunakan top (2) dalam kueri karena, perlu memeriksa apakah ada baris kedua yang cocok dengan kriteria dan jika ya, itu akan membuat pengecualian. Pada dasarnya SingleOrDefaultAnda mengatakan bahwa Anda ingin melempar pengecualian jika kueri Anda mengembalikan lebih dari 1 catatan.

zeeshanhirani
sumber
5
Pernahkah Anda mengukur perbedaan kinerja antara FirstOrDefaultdan SingleOrDefaultmenjadi signifikan? Saya akan mengatakan itu adalah pengoptimalan prematur dalam banyak kasus.
Steven
Saya cenderung menggunakan Single()atau SingleOrDefault()ketika saya mengembalikan sesuatu yang seharusnya hanya ada satu . Alasan saya melakukannya adalah untuk menemukan bug dengan membuat kueri yang ditulis dengan buruk, yang menghasilkan lebih dari yang seharusnya, gagal. Setidaknya dalam pikiran saya, ini akan membantu menjaga konsistensi data dalam sistem. Tentu saja ini lebih lambat, tapi saya rasa tidak lebih lambat, dan saya bersedia membayar harga itu.
mortb
15

Ini sangat sederhana: Singlemengembalikan satu item dan memberikan pengecualian jika tidak ada atau lebih dari satu item. Firstakan mengembalikan barang pertama atau melempar jika tidak ada barang. FirstOrDefaultakan mengembalikan item pertama atau mengembalikan nilai default ( nulljika tipe yang diberikan adalah tipe referensi) ketika tidak ada item.

Ini adalah perilaku yang seharusnya dimiliki API. Namun perlu diperhatikan bahwa implementasi yang mendasari dapat memiliki perilaku yang berbeda. Meskipun Entity Framework mematuhi hal ini, O / RM seperti LLBLGen juga dapat kembali nullsaat memanggil Firstyang merupakan hal yang sangat aneh. Ini adalah keputusan yang sangat aneh (dan keras kepala) oleh desainer IMO.

Steven
sumber
Terima kasih Steven. Saya kira saya masih bertanya-tanya mengapa Anda menggunakan salah satu dari yang lain? Saya selalu menggunakan FirstOrDefault (), dan ingin tahu mengapa banyak contoh baru yang saya lihat telah beralih ke Single (). Apakah ada alasan untuk beralih ke Single ()? Apakah ada orang lain yang juga mencapai hal yang sama, yang harus saya pertimbangkan?
asfsadf
7
Jika Anda ingin kode Anda "gagal cepat", First () dan Single () biarkan kode Anda lebih tepat mengatakan apa yang diharapkan (sehingga bisa gagal jika tidak)
Frank Schwieterman
3
Saya sangat setuju dengan Frank. Ini juga tentang mengkomunikasikan niat. Singlemenyatakan dengan jelas bahwa Anda hanya mengharapkan hasil memiliki satu elemen.
Steven
8

Keempat metode masing-masing memiliki tempatnya; Padahal Anda sebenarnya hanya memiliki dua operasi yang berbeda.

  • Pertama - Mengharapkan set hasil yang berisi banyak item, berikan saya item pertama dalam set itu.
  • Single - Mengharapkan hasil tunggal kembali, berikan saya item itu.

Versi xxxxOrDefault () hanya menambahkan "Saya tidak ingin menganggap kumpulan hasil kosong sebagai keadaan luar biasa."

Chris Shaffer
sumber
OK, jadi menurut saya First () jarang berguna. Saya kesulitan membuat skenario di mana Single () tidak akan menjadi opsi pertama. Anda punya yang cepat, kebetulan? Terima kasih.
asfsadf
3
Sayangnya banyak pengembang menggunakan First () atau FirstOrDefault () murni sebagai tindakan defensif, mengira itu akan menghindari pengecualian ketika itu benar-benar hanya berpotensi untuk menyembunyikan masalah nyata.
Matt H
3

Di sisi lain, Anda dapat membagi metode ini dengan logika inti, seperti ini:

  • Metode akan menanyakan database secara langsung : Single (), SingleOrDefault (), First (), FirstOrDefault ()
  • Metode akan melakukan pencarian di cache bahkan sebelum mengeluarkan kueri terhadap database : Find ()

Untuk beberapa detail kinerja, terutama dalam kasus kedua, Anda dapat melihat di sini: https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3

Selain itu, di grup pertama Anda dapat menentukan kueri kompleks, tetapi dengan metode Find () Anda hanya dapat memberikan kunci entitas untuk pencarian.

Kryszal
sumber
0

Single () dan SingleOrDefault () biasanya digunakan pada pengenal unik seperti ID, sedangkan First () atau FirstOrDefault () biasanya digunakan untuk kueri yang bisa memiliki beberapa hasil tetapi Anda hanya menginginkan "Top 1" .

Single () atau First () akan memunculkan pengecualian jika tidak ada hasil yang dikembalikan, SingleOrDefault () dan FirstOrDefault () menangkap pengecualian dan mengembalikan null atau default (ResultDataType).

MilkTea027
sumber