Akıcı ve Sorgu İfadesi - Birinin diğerine göre bir faydası var mı?


255

LINQ, jeneriklerden beri .NET'in en büyük geliştirmelerinden biridir ve bana tonlarca zaman ve kod satırı kazandırır. Ancak, akıcı sözdizimi benim için sorgu ifadesi sözdiziminden çok daha doğal görünüyor.

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();

İkisi arasında herhangi bir fark var mı veya birinin diğerine göre belirli bir faydası var mı?


1
Karmaşık sorgular için lambda sözdizimini daha anlaşılır / okunabilir buluyorum, ancak sorgu sözdizimini sadece daha güzel buluyorum.
nawfal

Yanıtlar:


255

İkisi de daha iyi: farklı ihtiyaçlara hizmet ediyorlar. Birden çok aralık değişkeninden yararlanmak istediğinizde sorgu sözdizimi kendi başına gelir . Bu üç durumda olur:

  • Let anahtar kelimesini kullanırken
  • Eğer (birden jeneratörler olduğunda gelen maddelerinde)
  • Katılırken

İşte bir örnek (LINQPad örneklerinden):

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;

Şimdi bunu yöntem sözdiziminde aynı şeyle karşılaştırın:

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);

Öte yandan yöntem sözdizimi, sorgu işleçlerinin tam gamını ortaya çıkarır ve basit sorgularla daha özlüdür. Sorgu ve yöntem sözdizimini karıştırarak her iki dünyanın en iyisini elde edebilirsiniz. Bu genellikle LINQ to SQL sorgularında yapılır:

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 };

2
Güzel cevap. ".Select (name => new {name, fName})" nin ne yaptığından biraz daha bahsedebilir misiniz?
quillbreaker

12
İsimsiz tipte tam adı ile birlikte tek tek kelimeyi (anne, williams, john, vb.) Seçer. Bu, sorgunun geri kalanında hem tam adı hem de tek tek kelimeye erişebilmeniz için orijinal tam adı "taşımanıza" olanak tanır.
Joe Albahari

58

Tüm ifadeyi bu şekilde yazabildiğim zaman (bazen "sorgu anlama sözdizimi" olarak adlandırılır) kullanmayı tercih ederim.

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

var title = titlesQuery.FirstOrDefault();

En kısa sürede eklemek zorundayım (parantez) ve .MethodCalls(), ben değiştiriyorum.

İlkini kullandığımda, genellikle her satıra bir cümle koyarım, şöyle:

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

Bunu okumayı biraz daha kolay buluyorum.


29

Her stilin artıları ve eksileri vardır. Sorgu sözdizimi, birleştirmeler söz konusu olduğunda daha güzeldir ve bir sorgu içinde geçici değişkenler oluşturmayı kolaylaştıran kullanışlı let anahtar kelimesine sahiptir.

Akıcı sözdiziminde ise sorgu sözdiziminde açıklanmayan çok daha fazla yöntem ve işlem vardır. Ayrıca sadece uzatma yöntemleri olduğu için kendi yazabilirsiniz.

Sorgu sözdizimini kullanarak bir LINQ deyimi yazmaya başladığımda her zaman parantez içine koymak ve akıcı LINQ uzantısı yöntemleri kullanarak geri düşmek zorunda bulduk. Sorgu sözdiziminin tek başına kullanmak için yeterli özelliği yoktur.


"onlar sadece uzatma yöntemleri olduğundan kendi yazabilirsiniz." - bu problemle karşılaşır mısın? stackoverflow.com/a/3850254/1175496
Kırmızı Bezelye

20

In VB.NET ben çok sorgu sözdizimi tercih ederim.

Çirkin Functionanahtar kelimeyi tekrarlamaktan nefret ediyorum :

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)

Bu temiz sorgu bence çok daha okunabilir ve bakımı kolay:

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

VB.NET'in sorgu sözdizimi de C # 'dan daha güçlü ve daha az ayrıntılı: https://stackoverflow.com/a/6515130/284240

Örneğin, bu LINQ - DataSet (Nesneler) sorgusu

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C #:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);

9
Sorgu stilini kullanamayan VB geliştiricileri için sempatilerim.
nawfal

1
Son C # örneğiniz değerli olamayacak kadar basit: basitçe `dataTable1.AsEnumerable () yazarsınız. Take (10);
Emyr

@Emyr: "VB.NET'in sorgu sözdizimi ile başlayan son paragrafım da C # 'dan daha güçlü ve daha az ayrıntılı" VB.NET'in sorgu sözdizimini C # ile karşılaştırıyor, yöntem sözdizimini kullanıyorsunuz.
Tim Schmelter

15

Sorgu sözdizimini hiç almıyorum. Aklımda bunun için hiçbir sebep yok. Izin vermek .Select ve anonim türleri ile elde edilebilir. Ben sadece orada "noktalama işaretleri" ile işler çok daha düzenli görünüyor düşünüyorum.


9
Akıcı sözdizimi ile birden çok birleşim oldukça çabuk yorucu olabilir. Genelde kendimi akıcı olarak kullanıyorum - katılmalar sürece.
Roman Starkov

1
@Instance Hunter: Burada da aynı. Akıcı sözdizimi fikrini anlamaya başlamam biraz zaman aldı. Güçlü numaralandırılabilir ve "saf" fonksiyonlar fikri ile birlikte, bundan gerçekten zevk alıyorum ve hoş kod gösterimi olmayan eski zor durumlardan hoşlanıyorum. Beynin ye-ole-SQL kısmı için, sorgu sözdizimine sahip olmak bir nimettir.
Xan-Kun Clark-Davis

13

Akıcı arayüz sadece bir yer varsa. Bir seçime veya siparişe ihtiyacım varsa, genellikle Sorgu sözdizimini kullanırım.


8

Akıcı sözdizimi gerçekten daha güçlü görünüyor, aynı zamanda küçük yeniden kullanılabilir yöntemlere kod düzenlemek için daha iyi çalışmalıdır.


5

Bu sorunun C # ile etiketlendiğini biliyorum, ancak Akıcı sözdizimi VB.NET ile acı verici bir şekilde ayrıntılı.


4

Akıcı sözdizimini gerçekten seviyorum ve mümkün olduğunca kullanmaya çalışıyorum, ancak bazı durumlarda, örneğin birleşimleri kullandığımda, genellikle Sorgu sözdizimini tercih ederim, bu durumlarda okumayı daha kolay buluyorum ve bence bazı insanlar Sorgu (SQL benzeri) sözdizimine lambdaslardan daha aşinadır.


4

Akıcı formatı anladığım ve sevdiğim halde, okunabilirlik nedenlerinden ötürü Query'ye yapıştım. LINQ ile tanışan insanlar Query'yi okumak için çok daha rahat bulacaklar.


4

Ben SQL kullanarak geleneksel web programlama gelen sorgu sözdizimini tercih ederim. Kafamı sarmak çok daha kolay. Ancak, kesinlikle çok daha kısa olduğu için .Where (lambda) kullanmaya başlayacağım düşünüyorum.


4

Yaklaşık 6 aydır Linq kullanıyorum. İlk kullanmaya başladığımda T-SQL'e çok benzediğinden sorgu sözdizimini tercih ettim.

Ancak, yavaş yavaş eskisine dönüyorum, çünkü yeniden kullanılabilir kod parçalarını uzatma yöntemleri olarak yazmak ve bunları birlikte zincirlemek kolaydır. Her bir maddeyi kendi satırına koymamda da okunabilirliğe çok yardımcı oluyor.


3

Şirketimizin standartlarını yeni oluşturdum ve Uzatma yöntemlerinin kullanılmasını zorunlu kılıyoruz. Ben diğerinden birini seçmek ve kod karıştırmayın iyi bir fikir olduğunu düşünüyorum. Uzantı yöntemleri diğer kod gibi daha fazla okunur.

Anlama sözdizimi tüm işleçlere sahip değildir ve sorgu etrafında parantez kullanır ve uzantı yöntemleri ekleme, en başta uzantı yöntemlerini kullanmak için bana yalvarır.

Ancak çoğunlukla, birkaç istisna dışında sadece kişisel tercihtir.


3
Kişisel tercihleri ​​uygulamayacağım .. Ama o benim.
Memet Olsen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.