Udostępnij za pomocą


Funkcje języka C#, które obsługują LINQ

Wyrażenia zapytań

Wyrażenia zapytań używają składni deklaratywnej podobnej do języka SQL lub XQuery do wykonywania zapytań dotyczących System.Collections.Generic.IEnumerable<T> kolekcji. W czasie kompilacji kompilator konwertuje składnię zapytań na wywołania metody do implementacji standardowych metod zapytań dostawcy LINQ. Aplikacje kontrolują standardowe operatory zapytań, które znajdują się w zakresie, określając odpowiednią przestrzeń nazw za pomocą dyrektywy using. Poniższe wyrażenie zapytania przyjmuje tablicę ciągów, grupuje je zgodnie z pierwszym znakiem w ciągu i porządkuje grupy.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Niejawnie wpisane zmienne (var)

Możesz użyć modyfikatora var , aby poinstruować kompilator wywnioskować i przypisać typ, jak pokazano poniżej:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Zmienne zadeklarowane jako var są silnie typizowane, podobnie jak zmienne, których typ został określony jawnie. Użycie var umożliwia tworzenie typów anonimowych, ale tylko dla zmiennych lokalnych. Aby uzyskać więcej informacji, zobacz Niejawnie wpisane zmienne lokalne.

Inicjatory obiektów i kolekcji

Inicjatory obiektów i kolekcji umożliwiają inicjowanie obiektów bez jawnego wywoływania konstruktora dla obiektu. Zazwyczaj inicjatory są używane w wyrażeniach zapytań podczas projekcji danych źródłowych do nowego typu danych. Zakładając, że istnieje klasa o nazwie Customer z właściwościami publicznymi Name i Phone, można użyć inicjatora obiektu jak w poniższym kodzie:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Kontynuując tę Customer klasę, załóżmy, że istnieje źródło danych o nazwie IncomingOrders, i że dla każdego zamówienia z dużym OrderSize elementem, chcesz utworzyć nową Customer na podstawie tego zamówienia. Możesz wykonać zapytanie LINQ w tym źródle danych i użyć inicjowania obiektu w celu wypełnienia kolekcji:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

Źródło danych może mieć więcej zdefiniowanych właściwości niż klasa Customer, takich jak OrderSize, ale dzięki inicjalizacji obiektu dane zwrócone z zapytania są przekształcane w pożądany typ danych. Wybierasz te, które są istotne dla twojej klasy. W rezultacie, teraz masz System.Collections.Generic.IEnumerable<T> wypełniony nowymi Customer, których chciałeś. Możesz również napisać powyższy przykład w składni metody LINQ:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

Począwszy od języka C# 12, możesz używać wyrażenia kolekcji do zainicjowania kolekcji.

Aby uzyskać więcej informacji, zobacz:

Typy anonimowe

Kompilator tworzy typ anonimowy. Tylko kompilator może uzyskać dostęp do nazwy typu. Typy anonimowe zapewniają wygodny sposób grupowania zestawu właściwości tymczasowo w wyniku zapytania bez konieczności definiowania oddzielnego nazwanego typu. Zainicjuj typy anonimowe za pomocą nowego wyrażenia i inicjatora obiektów, jak pokazano poniżej:

select new {name = cust.Name, phone = cust.Phone};

Począwszy od C# 7, możesz użyć krotek do tworzenia nienazwanych typów.

Elementy członkowskie rozszerzenia

Składowa rozszerzenia jest statycznym elementem członkowskim klasy statycznej skojarzonej z typem nazywanym typem odbiorcy. Można wywołać element członkowski rozszerzenia tak, jakby był członkiem typu odbiornika. Ta funkcja umożliwia "dodawanie" nowych członków do istniejących typów bez faktycznej modyfikacji. Standardowe operatory zapytań to zestaw metod rozszerzeń, które zapewniają funkcje zapytań LINQ dla dowolnego typu, który implementuje metodę IEnumerable<T>.

Wyrażenia lambda

Wyrażenie lambda jest funkcją śródliniową, która używa => operatora do oddzielania parametrów wejściowych od treści funkcji i może zostać przekonwertowana w czasie kompilacji na delegata lub drzewo wyrażeń. W programowaniu LINQ występują wyrażenia lambda podczas wykonywania wywołań metod bezpośrednich do standardowych operatorów zapytań.

Wyrażenia jako dane

Obiekty zapytania są komponowalne, co oznacza, że można zwrócić zapytanie z metody. Obiekty reprezentujące zapytania nie przechowują wynikowej kolekcji, ale raczej kroki umożliwiające wygenerowanie wyników w razie potrzeby. Zaletą zwracania obiektów zapytań z metod jest możliwość dalszego tworzenia lub modyfikowania ich. W związku z tym każda zwracana wartość lub out parametr metody zwracającej zapytanie musi również mieć ten typ. Jeśli metoda zmaterializuje zapytanie do konkretnego List<T> lub Array typu, zwraca wyniki zapytania zamiast samego zapytania. Nadal można tworzyć lub modyfikować zmienną kwerendy zwracaną z metody.

W poniższym przykładzie pierwsza metoda QueryMethod1 zwraca zapytanie jako wartość zwracaną, a druga metoda QueryMethod2 zwraca zapytanie jako out parametr (returnQ w przykładzie). W obu przypadkach jest to zapytanie, które jest zwracane, a nie wyniki zapytania.

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ = from i in ints
              where i < 4
              select i.ToString();

int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var myQuery1 = QueryMethod1(nums);

foreach Poniższa pętla wykonuje zapytanie myQuery1.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

Najedź wskaźnikiem myszy na myQuery1, aby zobaczyć jego typ.

Można również bezpośrednio wykonać zapytanie zwrócone przez QueryMethod1, bez użycia myQuery1.

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

Umieść wskaźnik myszy nad wywołaniem QueryMethod1, aby zobaczyć jego typ zwracany.

QueryMethod2 Zwraca zapytanie jako wartość jego out parametru:

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

Zapytanie można modyfikować przy użyciu kompozycji zapytań. W tym przypadku poprzedni obiekt zapytania jest używany do tworzenia nowego obiektu zapytania. Ten nowy obiekt zwraca inne wyniki niż oryginalny obiekt zapytania.

myQuery1 = from item in myQuery1
           orderby item descending
           select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}