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, OrderBy və ToList — 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-ı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-ı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 | |
|
| 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, , 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 |
Adətən , amma bəzən siyahı üçün 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)).
GO TO FULL VERSION