CodeGym /Kurslar /C# SELF /LINQ Sintaksisi: Method Syntax vs Query Syntax

LINQ Sintaksisi: Method Syntax vs Query Syntax

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

LINQ dünyasında sorğuları yazmaq üçün iki əsas "məktəb", iki stil var ki, ilk baxışdan tamamilə fərqli görünə bilər. Bunlar Query Syntax (sorğu sintaksisi) və Method Syntax (metod sintaksisi)-dir. Əgər heç vaxt düşünmüsənsə ki, proqramlaşdırma sırf məntiqdir, bu gün bir az sənət qatacağıq, çünki sintaksis seçimi çox vaxt fırça ilə karandaş arasında seçim kimidir: hər ikisi çəkir, amma biri rəngi, digəri isə konturu daha yaxşı verir.

Niyə iki sintaksis var? Yaxşı sualdır! Təsəvvür elə, kofe sifariş etmək istəyirsən. Deyə bilərsən: "Zəhmət olmasa, bir fincan espresso süd və bir qaşıq şəkərlə?". Ya da kağızda yaza bilərsən: "Espresso. Süd. 1 şəkər". Hər ikisi başa düşüləndir, amma biri daha danışıq tərzində, digəri isə daha qısa.

LINQ-də də belədir. Bir sintaksis SQL-ə maksimal bənzəsin deyə yaradılıb, digəri isə daha "C#-vari" və çevik olsun deyə. Axırda isə C# kompilyatoru hər iki sintaksisi eyni şeyə çevirir: metod çağırışlarına. Yəni seçim çox vaxt oxunaqlılıq və şəxsi zövq məsələsidir.

Gəlin hər ikisinə baxaq.

2. Method Syntax

Bu variantda sən LINQ extension metodlarını nöqtə ilə bir-birinin ardınca çağırırsan. Bu yanaşma .NET developer-lar arasında çox populyardır, çünki yeni əməliyyatlar əlavə etmək asandır, nəticə həmişə IEnumerable<T> olur və kodun içində yazmaq rahatdır.

Nümunə: Məhsulları filtrləmək və sıralamaq


var filteredProducts = products
    .Where(p => p.Price < 1000)          // Qiymətə görə filtr
    .OrderBy(p => p.Name)                // Ada görə sıralama
    .ToList();                           // List<Product>-a çeviririk

Where, OrderByToList — LINQ extension metodlarıdır, hər biri yeni data set qaytarır və onu daha da işləmək olur.

Diagram


graph LR
A[products] --> B[Where]
B --> C[OrderBy]
C --> D[ToList]
Method Syntax-da çağırış ardıcıllığı

Method Syntax-ın üstünlükləri

  • Çox çevikdir: bir çox əməliyyatdan ibarət mürəkkəb zəncirlər qurmaq asandır.
  • Bütün metodlar sadəcə C# metodlarıdır, IDE autocomplete kömək edir.
  • LINQ-də olan demək olar hər şeyi (hətta daha çoxunu) etmək olur.

Başqa nümunə: 18 yaşdan yuxarı bütün istifadəçilərin adlarını seçmək

Tutaq ki, bizdə User klası var:


public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

İndi böyüklərin adlarını seçirik:


List<User> users = ... // hardasa elan olunub

var adultNames = users
    .Where(u => u.Age >= 18)
    .Select(u => u.Name)
    .ToList();

3. Query Syntax (SQL-ə bənzər sintaksis)

Bu sintaksis xüsusi olaraq yaradılıb ki, C# developer-lar özlərini SQL-də işləyirmiş kimi hiss etsinlər. O, verilənlər bazasına sorğu yazmağa bənzəyir və from açar sözü ilə başlayır.

Nümunə: eyni filtr və sıralama


var filteredProducts = 
    from p in products
    where p.Price < 1000
    orderby p.Name
    select p;

Burada hər şey klassik sorğu kimi oxunur: "products kolleksiyasından p götür, p.Price < 1000 olanları seç, p.Name-ə görə sırala, p-ni seç".

Diagram


flowchart TD
    A[products] -->|from p in products| B[where p.Price < 1000]
    B --> C[orderby p.Name]
    C --> D[select p]
Query Syntax-da sorğu mərhələləri

Query Syntax-ın üstünlükləri

  • SQL-ə bənzəyir, ona görə də verilənlər bazası ilə işləyənlər üçün daha başadüşüləndir.
  • Bir neçə şərt, qruplaşdırma, join olan uzun sorğular üçün daha oxunaqlıdır.

Başqa nümunə: böyüklərin adlarını seçmək


var adultNames = 
    from u in users
    where u.Age >= 18
    select u.Name;

Diqqət et: Burada select-dən sonra bütün obyekti yox, konkret bir sahəni — məsələn, təkcə adı seçmək olur.

4. Müqayisə: Method Syntax vs Query Syntax

Method Syntax Query Syntax
Sintaksis
users.Where(...).Select(...)
from u in users where ... select ...
Nəyə bənzəyir Adi metodlar/zəncirlər SQL
Harada tətbiq olunur Hər zaman, istənilən əməliyyat üçün Bütün əməliyyatlar əlçatan deyil (məsələn,
Sum
,
Count
yalnız Method Syntax-da)
Oxunaqlılıq Zəncirlər üçün yaxşıdır Qruplaşdırma, join üçün daha rahatdır
Nə qaytarır Adətən
IEnumerable<T>
Adətən
IEnumerable<T>
, amma bəzən siyahı üçün
.ToList()
lazımdır

Həyatdan maraqlı fakt

Microsoft-un rəsmi LINQ sənədlərində əksər nümunələr hər iki stildə verilir. Amma real kodda daha çox Method Syntax istifadə olunur — çünki extension metodlarla işləmək daha rahatdır (Where, Select, OrderBy və s.).

Qarışdırmaq olar, ya yox? Hansı stili seçmək?

Olar hər iki sintaksisi bir layihədə (hətta bir sorğuda) qarışdırmaq — amma bu bir az qəribə görünür. Əsas odur ki, kodu "salat"a çevirmə. Adətən bir modul və ya layihə üçün bir stil seçirlər ki, kod oxunaqlı olsun.

Method Syntax ardıcıl çevrilmələr və yalnız metod şəklində olan bütün LINQ metodlarından istifadə üçün əladır (Sum, Count, Any və bəziləri).

Query Syntax isə join, group by və ya mürəkkəb çoxsəviyyəli şərtlər üçün çox rahatdır — oxunaqlılıqda üstünlük verir.

5. Stilər arasında çevirmə: eyni şey, fərqli yazılış

C#-da LINQ istənilən SQL-ə bənzər sorğunu (Query Syntax) metod çağırışları zəncirinə (Method Syntax) çevirir. Yəni nə yazırsansa-yaz, C# kompilyasiya zamanı bunu extension metodlara çevirəcək.

Nümunə 1 — filtrasiya:

Query Syntax:


var adults = from u in users
             where u.Age >= 18
             select u;

Method Syntax (ekvivalent):


var adults = users.Where(u => u.Age >= 18);

Nümunə 2 — sahələrin seçilməsi (Select):

Query Syntax:


var names = from u in users
            select u.Name;

Method Syntax:


var names = users.Select(u => u.Name);

7. Qruplaşdırma və birləşdirmə (join, group by)

Yeni obyektlərin yaradılması

Gəlin tədris tətbiqimizə istifadəçiləri yaşa görə qruplaşdırıb siyahı çıxarmaq imkanı əlavə edək. Burada sintaksis fərqi daha aydın görünür.

Query Syntax (qruplaşdırma):


var usersByAge = 
    from u in users
    group u by u.Age into ageGroup
    select new { Age = ageGroup.Key, Users = ageGroup.ToList() };

Burada istifadəçiləri yaşa görə qruplaşdırırıq (group u by u.Age). into-dan sonra ageGroup dəyişəni yaranır — bu artıq qrupun özüdür.

Method Syntax (ekvivalent):


var usersByAge = users
    .GroupBy(u => u.Age)
    .Select(ageGroup => new { Age = ageGroup.Key, Users = ageGroup.ToList() });

Daha çətin: birləşdirmə (join)

Tutaq ki, bizdə sifarişlər (orders) və istifadəçilər (users) siyahısı var. İstifadəçilərin adlarını və onların sifarişlərinin cəmini almaq istəyirik.

Query Syntax:


var userOrders =
    from user in users
    join order in orders on user.Id equals order.UserId
    select new { user.Name, order.Amount };

Method Syntax:


var userOrders = users.Join(
    orders,
    user => user.Id,
    order => order.UserId,
    (user, order) => new { user.Name, order.Amount }
);

8. Tez-tez rast gəlinən səhvlər, tələlər və lifehack-lər

Ən çox rast gəlinən yanlışlardan biri: əgər sən .ToList() əlavə etməmisənsə, nəticə — siyahı yox, "təxirə salınmış sorğu" (lazy query)-dur, hansı ki, yalnız ilk dəfə dövrə salanda işləyəcək. Bu rahatdır, amma əgər ilkin kolleksiya sorğudan sonra dəyişərsə, gözlənilməz nəticələrə gətirə bilər. "Təxirə salınmış icra" barədə ayrıca danışacağıq (LINQ metodları ilə tanışlıqdan sonra).

Bir çox yeni başlayanlar qarışdırır ki, Query Syntax-da bütün LINQ metodlarını istifadə etmək olmur. Məsələn, sadəcə select sum(u.Age) yazmaq olmur, Method Syntax-a keçmək lazımdır (users.Sum(u => u.Age)).

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION