Ekspresi Fasih dan Kueri - Apakah ada manfaat satu di atas yang lain?

255

LINQ adalah salah satu perbaikan terhebat untuk .NET sejak generik dan ini menghemat waktu, dan baris kode. Namun, sintaks yang lancar tampaknya jauh lebih alami bagi saya daripada sintaks ekspresi kueri.

var title = entries.Where(e => e.Approved)
    .OrderBy(e => e.Rating).Select(e => e.Title)
    .FirstOrDefault();

var query = (from e in entries
             where e.Approved
             orderby e.Rating
             select e.Title).FirstOrDefault();

Apakah ada perbedaan di antara keduanya atau apakah ada manfaat tertentu dari satu di atas yang lain?

JarrettV
sumber
1
Untuk pertanyaan kompleks, saya menemukan sintaks lambda lebih dapat dimengerti / dibaca, tetapi sintaks query hanya lebih cantik.
nawfal

Jawaban:

255

Tidak ada yang lebih baik: mereka melayani kebutuhan yang berbeda. Sintaks kueri muncul dengan sendirinya saat Anda ingin memanfaatkan berbagai variabel rentang . Ini terjadi dalam tiga situasi:

  • Saat menggunakan kata kunci let
  • Ketika Anda memiliki beberapa generator ( dari klausa)
  • Ketika melakukan bergabung

Berikut ini sebuah contoh (dari sampel LINQPad):

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };

var query =
  from fullName in fullNames
  from name in fullName.Split()
  orderby fullName, name
  select name + " came from " + fullName;

Sekarang bandingkan ini dengan hal yang sama dalam sintaks metode:

var query = fullNames
  .SelectMany (fName => fName.Split().Select (name => new { name, fName } ))
  .OrderBy (x => x.fName)
  .ThenBy  (x => x.name)
  .Select  (x => x.name + " came from " + x.fName);

Sintaks metode, di sisi lain, memperlihatkan keseluruhan penuh operator kueri dan lebih ringkas dengan kueri sederhana. Anda bisa mendapatkan yang terbaik dari kedua dunia dengan mencampur sintaks kueri dan metode. Ini sering dilakukan dalam permintaan LINQ to SQL:

var query =
  from c in db.Customers
  let totalSpend = c.Purchases.Sum (p => p.Price)    // Method syntax here
  where totalSpend > 1000
  from p in c.Purchases
  select new { p.Description, totalSpend, c.Address.State };
Joe Albahari
sumber
2
Jawaban bagus. Bisakah Anda memberi tahu saya sedikit lebih banyak tentang apa yang ". Pilih (name => new {name, fName})" lakukan?
quillbreaker
12
Ini memilih kata individual (anne, williams, john, dll) bersama dengan nama lengkap dalam jenis anonim. Ini memungkinkan Anda untuk "membawa" nama lengkap asli sehingga Anda memiliki akses ke nama lengkap dan kata individual di sisa kueri.
Joe Albahari
58

Saya lebih suka menggunakan yang terakhir (kadang-kadang disebut "sintaks pemahaman query") ketika saya bisa menulis seluruh ekspresi seperti itu.

var titlesQuery = from e in entries
                  where e.Approved
                  orderby e.Rating
                  select e.Titles;

var title = titlesQuery.FirstOrDefault();

Begitu saya harus menambahkan (tanda kurung) dan .MethodCalls(), saya berubah.

Ketika saya menggunakan yang pertama, saya biasanya meletakkan satu klausa per baris, seperti ini:

var title = entries
    .Where (e => e.Approved)
    .OrderBy (e => e.Rating)
    .Select (e => e.Title)
    .FirstOrDefault();

Saya menemukan itu sedikit lebih mudah dibaca.

Jay Bazuzi
sumber
29

Setiap gaya memiliki pro dan kontra. Sintaks kueri lebih baik ketika bergabung dan memiliki kata kunci let yang berguna yang membuat membuat variabel sementara di dalam kueri menjadi mudah.

Sintaks yang lancar di sisi lain memiliki lebih banyak metode dan operasi yang tidak diekspos melalui sintaks kueri. Juga karena mereka hanya metode ekstensi Anda dapat menulis sendiri.

Saya telah menemukan bahwa setiap kali saya mulai menulis pernyataan LINQ menggunakan sintaks kueri akhirnya saya harus memasukkannya dalam tanda kurung dan kembali menggunakan metode ekstensi LINQ yang lancar. Sintaks kueri tidak memiliki cukup fitur untuk digunakan dengan sendirinya.

James Newton-King
sumber
"Karena itu hanyalah metode ekstensi, kamu bisa menulis sendiri." - Apakah Anda akan mengalami masalah ini? stackoverflow.com/a/3850254/1175496
The Red Pea
20

Dalam VB.NET saya lebih suka sintaks kueri.

Aku benci mengulangi kata-kata jelek Function:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };
Dim query =
     fullNames.SelectMany(Function(fName) fName.Split().
     Select(Function(Name) New With {Name, fName})).
     OrderBy(Function(x) x.fName).
     ThenBy(Function(x) x.Name).
     Select(Function(x) x.Name & " came from " & x.fName)

Query yang rapi ini jauh lebih mudah dibaca dan dikelola menurut saya:

query = From fullName In fullNames
        From name In fullName.Split()
        Order By fullName, name
        Select name & " came from " & fullName

Sintaks kueri VB.NET juga lebih kuat dan tidak terlalu bertele-tele daripada di C #: https://stackoverflow.com/a/6515130/284240

Misalnya kueri LINQ to DataSet (Objects) ini

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C #:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);
Tim Schmelter
sumber
9
Simpati saya untuk para pengembang VB yang tidak bisa menggunakan gaya permintaan.
nawfal
1
Contoh C # terakhir Anda terlalu sederhana untuk menjadi berharga: Anda cukup menulis `dataTable1.AsEnumerable (). Ambil (10);
Emyr
@Emyr: paragraf terakhir saya yang dimulai dengan "sintaks kueri VB.NET juga lebih kuat dan lebih sedikit verbose daripada di C #" hanya membandingkan sintaks kueri VB.NET dengan C #, Anda menggunakan sintaksis metode.
Tim Schmelter
15

Saya tidak mendapatkan sintaks kueri sama sekali. Tidak ada alasan untuk itu dalam pikiran saya. biarkan dapat dicapai dengan. Pilih dan jenis anonim. Saya hanya berpikir hal-hal terlihat jauh lebih terorganisir dengan "tanda baca" di sana.

Pemburu Instance
sumber
9
Multiple joins bisa sangat melelahkan dengan sintaks yang lancar. Saya biasanya menggunakan fasih sendiri - kecuali jika ada yang terlibat.
Roman Starkov
1
@Instance Hunter: Sama di sini. Butuh waktu cukup lama bagi saya untuk mulai memahami gagasan sintaks yang lancar. Dalam kombinasi dengan enumerable yang kuat dan ide fungsi "murni", saya sekarang benar-benar menikmatinya, dan sebelumnya situasi rumit yang tidak memiliki representasi kode yang bagus. Untuk kamu-ole-SQL-bagian otak, masih merupakan berkah untuk memiliki sintaks query.
Xan-Kun Clark-Davis
13

Antarmuka yang lancar jika hanya ada di mana. Jika saya memerlukan pilih atau orderby, saya biasanya menggunakan sintaks Query.

James Curran
sumber
8

Sintaks yang lancar memang tampak lebih kuat, itu juga harus bekerja lebih baik untuk mengatur kode menjadi metode yang dapat digunakan kembali.

Kozyarchuk
sumber
5

Saya tahu pertanyaan ini ditandai dengan C #, tetapi sintaks Fasih berselisih dengan VB.NET.

Larsenal
sumber
4

Saya sangat suka sintaks Fasih dan saya mencoba menggunakannya di mana saya bisa, tetapi dalam kasus-kasus tertentu, misalnya di mana saya menggunakan bergabung, saya biasanya lebih suka sintaks Query, dalam kasus-kasus saya merasa lebih mudah dibaca, dan saya pikir beberapa orang lebih akrab dengan sintaks Query (seperti SQL), daripada lambdas.

CMS
sumber
4

Meskipun saya mengerti dan menyukai format yang lancar, saya tetap menggunakan Query untuk sementara waktu karena alasan keterbacaan. Orang-orang yang baru saja diperkenalkan ke LINQ akan menemukan Query jauh lebih nyaman untuk dibaca.

Lisb
sumber
4

Saya lebih suka sintaks kueri karena saya berasal dari pemrograman web tradisional menggunakan SQL. Jauh lebih mudah bagi saya untuk membungkus kepala saya. Namun, saya pikir saya akan mulai memanfaatkan. Di mana (lambda) karena pasti jauh lebih pendek.

Steve Tranby
sumber
4

Saya telah menggunakan Linq selama sekitar 6 bulan sekarang. Ketika saya pertama kali mulai menggunakannya saya lebih suka sintaks query karena sangat mirip dengan T-SQL.

Tapi, saya secara bertahap datang ke yang sekarang, karena mudah untuk menulis potongan kode yang dapat digunakan kembali sebagai metode ekstensi dan hanya rantai mereka bersama. Meskipun saya menemukan menempatkan setiap klausa pada barisnya sendiri banyak membantu dengan keterbacaan.

Antony Scott
sumber
3

Saya baru saja menetapkan standar perusahaan kami dan kami menegakkan penggunaan metode Extension. Saya pikir itu ide yang baik untuk memilih satu dari yang lain dan jangan mencampurnya dalam kode. Metode ekstensi lebih banyak membaca seperti kode lainnya.

Sintaks pemahaman tidak memiliki semua operator dan menggunakan tanda kurung di sekitar kueri dan menambahkan metode ekstensi setelah semua hanya meminta saya untuk menggunakan metode ekstensi dari awal.

Tetapi sebagian besar itu hanya preferensi pribadi dengan beberapa pengecualian.

Rodi
sumber
3
Saya tidak akan memaksakan preferensi pribadi .. Tapi itu saya.
Memet Olsen