LINQ w C# – kompletny przewodnik z przykładami i najlepszymi praktykami
LINQ w C# (Language Integrated Query) to jedno z tych narzędzi, które realnie zmieniają sposób myślenia o danych. Umożliwia czytelne, deklaratywne i bezpieczne typowo przetwarzanie kolekcji, baz danych, XML, JSON czy danych z API – bez opuszczania języka C#. W tym artykule poznasz czym jest LINQ, jak działa, gdzie go używać oraz zobaczysz praktyczne przykłady LINQ w realnych scenariuszach projektowych.
Czym jest LINQ (Language Integrated Query)?
LINQ (Language Integrated Query) to rozszerzenie języka C# wprowadzone przez Microsoft, które pozwala wykonywać zapytania do danych bezpośrednio w kodzie, przy użyciu jednolitej składni.
Zamiast:
- pętli
foreach - instrukcji warunkowych
- ręcznego mapowania danych
otrzymujesz deklaratywne zapytania, podobne do SQL, ale w pełni typowane i sprawdzane na etapie kompilacji.
Dlaczego LINQ jest tak popularny w .NET?
Jednolita składnia zapytań
Te same operatory (Where, Select, GroupBy) działają:
- na kolekcjach w pamięci (
List<T>) - w Entity Framework
- na XML
- na JSON
- na danych z API
Silne typowanie
Błędy typów wykrywane są w czasie kompilacji, a nie dopiero w runtime.
IntelliSense i refaktoryzacja
Visual Studio rozumie LINQ – podpowiada metody, wykrywa błędy, wspiera refaktoryzację.
Czytelność i testowalność
Kod oparty o LINQ:
- jest krótszy
- łatwiejszy do testowania
- prostszy w utrzymaniu
Składnia LINQ – dwie drogi, ten sam cel
LINQ Method Syntax (najczęściej używana)
var adults = people.Where(p => p.Age > 25);
LINQ Query Syntax (bardziej SQL-owa)
var adults =
from p in people
where p.Age > 25
select p;
Technicznie obie formy są równoważne – kompilator zamienia Query Syntax na Method Syntax.
Oto kilka przykładów zastosowania LINQ w różnych scenariuszach:
Filtrowanie danych (Where)
Wyszukaj osoby w kolekcji, które mają więcej niż 25 lat.
var adults = people.Where(person => person.Age > 25);
Używaj do:
- walidacji
- filtrów użytkownika
- logiki biznesowej
Sortowanie (OrderBy, ThenBy)
Posortuj listę produktów według ceny.
var sortedProducts = products
.OrderBy(p => p.Price)
.ThenBy(p => p.Name);
Pobieranie fragmentu danych (Take, Skip)
var top5Products = products.Take(5);
Idealne do:
- paginacji
- dashboardów
- API
Grupowanie (GroupBy)
Pogrupuj osoby według miasta zamieszkania.
var groupedByCity = people.GroupBy(p => p.City);
Agregacje (Count, Sum, Average, Max)
int count = people.Count(p => p.Age > 18);
double avg = numbers.Average();
int max = numbers.Max();
Łączenie danych:
Połącz listę zamówień z klientami w oparciu o identyfikator klienta.
var joinedData = orders.Join(
customers,
order => order.CustomerId,
customer => customer.Id,
(order, customer) => new
{
order.Id,
customer.Name,
order.TotalValue
});
Najczęstsze zastosowanie:
- relacje 1-N
- raporty
- DTO do API
Pobieranie konkretnej ilości elementów:
Pobierz pierwszych 5 produktów z listy.
var top5Products = products.Take(5);
Pobieranie unikalnych elementów:
Pobierz unikalne miasta z listy zamówień.
var uniqueCities = orders.Select(order => order.City).Distinct();
Zliczanie elementów w kolekcji:
Oblicz, ile osób w kolekcji ma wiek powyżej 18 lat.
int adultCount = people.Count(person => person.Age > 18);
Agregacja danych:
Oblicz sumę, średnią lub maksimum wartości w kolekcji.
int sum = numbers.Sum();
double average = numbers.Average();
int max = numbers.Max();
Filtrowanie danych zagnieżdżonych:
Wybierz wszystkie książki napisane przez autora o nazwisku “Smith”.
var booksBySmith = library
.Where(author => author.Name == "Smith")
.SelectMany(author => author.Books);
Działania na elementach w kolekcji:
Dodaj 10 do każdej wartości w liście.
var updatedList = numbers.Select(number => number + 10).ToList();
Wyszukiwanie wzorców:
Wyszukaj słowa rozpoczynające się na literę “A” w liście słów.
var wordsStartingWithA = words
.Where(word => word.StartsWith("A", StringComparison.OrdinalIgnoreCase));
Operacje na danych XML:
Analiza danych XML w celu wydobycia potrzebnych informacji.
var query = from element in xmlDocument.Descendants("Book")
where (int)element.Element("Price") > 20
select element.Element("Title").Value;
Operacje na bazie danych SQL:
Użyj LINQ to SQL do wykonywania zapytań do bazy danych SQL.
var highValueOrders = dbContext.Orders
.Where(order => order.TotalValue > 1000);
Zapytania do danych JSON:
Analiza danych w formacie JSON.
var highIncomeCustomers = jsonCustomers
.Where(customer => customer["Income"]
.Value<int>() > 50000);
Zastosowanie dynamicznego LINQ:
Tworzenie zapytań w sposób dynamiczny, na przykład na podstawie warunków użytkownika.
var filteredData = data.Where("Age > 30 && City == \"New York\"");
Wykonywanie operacji równoległych:
Wykonanie operacji LINQ na wielu wątkach w celu zwiększenia wydajności.
var parallelQuery = data.AsParallel().Where(item => item.Value > 50);
Tworzenie zapytań skomplikowanych i bardziej zaawansowanych:
Kombinowanie różnych operacji LINQ, aby uzyskać bardziej skomplikowane wyniki.
var result = from order in orders
join customer in customers on order.CustomerId equals customer.Id
where customer.Country == "USA"
group order by order.Product into productGroup
select new
{
Product = productGroup.Key,
TotalSales = productGroup.Sum(o => o.Quantity)
};
Analiza tekstu:
Wydobądź unikalne słowa z tekstu i posortuj je według liczby wystąpień.
string text = "To jest przykład zastosowania LINQ w analizie tekstu. LINQ to potężne narzędzie.";
var uniqueWords = text.Split(' ')
.Select(word => word.ToLower())
.Where(word => !string.IsNullOrWhiteSpace(word))
.GroupBy(word => word)
.OrderByDescending(group => group.Count())
.Select(group => $"{group.Key}: {group.Count()}");
Znajdowanie palindromów:
Znajdź wszystkie palindromy w danej kolekcji słów.
var palindromes = words.Where(word => word.SequenceEqual(word.Reverse()));
Analiza logów:
Wykorzystaj LINQ do analizy logów zapisywanych w plikach lub bazach danych. Na przykład, znajdź wszystkie logi błędów w danym okresie czasu.
var errorLogs = logs
.Where(log => log.LogType == LogType.Error
&& log.Timestamp >= startTime
&& log.Timestamp <= endTime);
Tworzenie generowania fraz acronimów:
Przetwórz listę fraz na akronimy.
var phrases = new List<string>
{ "Language Integrated Query", "World Wide Web", "Artificial Intelligence" };
var acronyms = phrases
.Select(phrase => new string(phrase.Split(' ')
.Select(word => word[0]).ToArray()));
Pobieranie danych geograficznych:
Wykorzystaj LINQ do pobrania danych geograficznych, takich jak kody pocztowe i koordynaty geograficzne, z zewnętrznego źródła, takiego jak API usług geolokalizacyjnych.
var locations = geolocationService.GetLocations()
.Where(location => location.ZipCode.StartsWith("90")
&& location.Latitude > 40);
Zastosowanie LINQ w grach:
W grach można użyć LINQ do zarządzania danymi dotyczącymi postaci, przedmiotów itp. Na przykład, wybierz wszystkie przedmioty w grze, których poziom jest wyższy niż poziom postaci.
var highLevelItems = gameItems.Where(item => item.RequiredLevel > player.Character.Level);
- Analiza mediów społecznościowych: Jeśli pracujesz nad projektem związanym z mediami społecznościowymi, możesz użyć LINQ do analizy postów i komentarzy, na przykład, aby znaleźć najpopularniejsze treści lub identyfikować wpisy z negatywnymi komentarzami.
- Rozwiązywanie łamigłówek: Stwórz program do rozwiązywania łamigłówek logicznych, takich jak sudoku, wykorzystując LINQ do generowania i analizy planszy.
- Automatyzacja pracy biurowej: Przy użyciu LINQ, automatyzuj pracę biurową, na przykład przeszukując i analizując dane w arkuszach kalkulacyjnych lub dokumentach tekstowych.
- Rekomendacje i analiza zachowań użytkowników: W aplikacjach internetowych i sklepach internetowych użyj LINQ do analizy zachowań użytkowników i generowania rekomendacji produktów.
Te oryginalne przykłady ilustrują, jak LINQ może być używane w różnych dziedzinach, aby przyspieszyć i ułatwić analizę i manipulację danymi. LINQ jest bardzo elastycznym narzędziem i może być dostosowane do wielu różnych zastosowań.
Najlepsze praktyki LINQ w C#
Checklist:
- ✅ Nie wywołuj
ToList()zbyt wcześnie - ✅ Czytaj zapytania jak zdania
- ✅ Oddziel LINQ od logiki biznesowej
- ✅ Uważaj na LINQ w pętlach
- ✅ Profiluj zapytania EF (
ToQueryString())
Kiedy NIE używać LINQ?
- bardzo krytyczne fragmenty performance
- ekstremalnie złożone algorytmy
- kod wymagający pełnej kontroli iteracji
Czasem zwykła pętla for jest… po prostu lepsza.
Oto kilka kluczowych cech LINQ:
- Jednolita składnia: LINQ wprowadza jednolitą składnię do wykonywania zapytań, niezależnie od źródła danych. Programiści mogą używać tych samych konstrukcji języka C# do przetwarzania różnych rodzajów danych.
- Typowanie: LINQ jest silnie zintegrowany z typami danych języka C#, co oznacza, że błędy typu można wykrywać na etapie kompilacji, co pomaga w uniknięciu błędów w trakcie działania programu.
- Wsparcie dla różnych źródeł danych: LINQ obsługuje wiele rodzajów źródeł danych, takich jak tablice, listy, kolekcje, bazy danych, pliki XML i inne.
- IntelliSense: LINQ w językach programowania .NET jest zintegrowany z narzędziami programistycznymi, takimi jak Visual Studio, co umożliwia korzystanie z funkcji IntelliSense do automatycznego uzupełniania zapytań LINQ i dostarczania sugestii podczas programowania.
- Wydajność optymalizowana: LINQ stara się optymalizować zapytania tak, aby były wydajne. Możesz kontrolować sposób, w jaki LINQ przetwarza zapytania i w jaki sposób są wykonywane.
- Rozszerzalność: Możesz tworzyć własne rozszerzenia LINQ i operatory, aby dostosować go do swoich potrzeb.
- Zapytania składane: Można łączyć wiele operatorów LINQ w jednym zapytaniu, tworząc bardziej zaawansowane zapytania. LINQ umożliwia budowanie zapytań skomplikowanych w sposób modułowy.
- Wsparcie dla anonimowych typów: LINQ pozwala na tworzenie anonimowych typów, które są przydatne w sytuacjach, gdy chcesz zwrócić zestaw właściwości z różnych źródeł danych.
- Zapytania asynchroniczne: LINQ obsługuje również zapytania asynchroniczne, co jest przydatne w aplikacjach, które korzystają z asynchronicznego programowania.
- Zapytania wyrażeniowe: Można używać wyrażeń LINQ, które są bardziej czytelne niż tradycyjne zapytania.
- Obsługa języka SQL: W przypadku baz danych można używać LINQ to SQL lub Entity Framework do wykonywania zapytań LINQ w języku SQL na bazie danych.
LINQ (Language Integrated Query) znajduje zastosowanie w wielu różnych kontekstach, zarówno dla kolekcji w pamięci, jak i dla różnych źródeł danych, takich jak bazy danych i XML.

