Podstawowe informacje o wyrażeniach zapytańQuery expression basics

W tym artykule przedstawiono podstawowe pojęcia związane z wyrażenia zapytań w języku C#.This article introduces the basic concepts related to query expressions in C#.

Co to jest zapytanie, a czego?What is a query and what does it do?

A zapytania to zbiór instrukcji w tym artykule opisano, jakie dane mają być pobranie z danego źródła danych (lub źródła) i jakie kształt i organizacji mają zwracanych danych.A query is a set of instructions that describes what data to retrieve from a given data source (or sources) and what shape and organization the returned data should have. Zapytanie różni się od wyników, które tworzy.A query is distinct from the results that it produces.

Ogólnie rzecz biorąc źródło danych jest zorganizowana logicznie jako sekwencję elementów tego samego rodzaju.Generally, the source data is organized logically as a sequence of elements of the same kind. Na przykład w tabeli bazy danych SQL zawiera sekwencję wierszy.For example, a SQL database table contains a sequence of rows. W pliku XML ma "kolejność" elementów XML (mimo że są one zorganizowane hierarchicznie w postaci struktury drzewiastej).In an XML file, there is a "sequence" of XML elements (although these are organized hierarchically in a tree structure). Kolekcja w pamięci zawiera sekwencję obiektów.An in-memory collection contains a sequence of objects.

Z punktu widzenia aplikacji określonego typu i struktury oryginalnych danych źródłowych nie jest ważna.From an application's viewpoint, the specific type and structure of the original source data is not important. Aplikacja zawsze widzi źródło danych jako IEnumerable<T> lub IQueryable<T> kolekcji.The application always sees the source data as an IEnumerable<T> or IQueryable<T> collection. Na przykład w składniku LINQ to XML, źródło danych jest widoczny jako IEnumerable < XElement>.For example, in LINQ to XML, the source data is made visible as an IEnumerable<XElement>.

Biorąc pod uwagę tę sekwencję źródła, zapytanie może wykonaj jedną z trzy rzeczy:Given this source sequence, a query may do one of three things:

  • Pobrać podzbiór elementów, aby utworzyć nową sekwencję bez modyfikowania poszczególnych elementów.Retrieve a subset of the elements to produce a new sequence without modifying the individual elements. Zapytanie może sortowanie i grupowanie zwracanej sekwencji na różne sposoby, jak pokazano w poniższym przykładzie (przyjęto założenie, scores jest int[]):The query may then sort or group the returned sequence in various ways, as shown in the following example (assume scores is an int[]):

    IEnumerable<int> highScoresQuery =
        from score in scores
        where score > 80
        orderby score descending
        select score;
    
  • Pobierają sekwencję elementów, jak w poprzednim przykładzie, ale przekształcanie ich pod kątem nowego typu obiektu.Retrieve a sequence of elements as in the previous example but transform them to a new type of object. Na przykład zapytanie może pobierać tylko nazwiska z niektórych rekordów klientów w źródle danych.For example, a query may retrieve only the last names from certain customer records in a data source. Lub może pobrać pełnego rekordu, a następnie używania jej do utworzenia innego typu obiektu w pamięci, a nawet danych XML przed wygenerowaniem sekwencji wynik końcowy.Or it may retrieve the complete record and then use it to construct another in-memory object type or even XML data before generating the final result sequence. W poniższym przykładzie pokazano projekcji z int do string.The following example shows a projection from an int to a string. Należy pamiętać, nowy typ highScoresQuery.Note the new type of highScoresQuery.

    IEnumerable<string> highScoresQuery2 =
        from score in scores
        where score > 80
        orderby score descending
        select $"The score is {score}";
    
  • Pobrać wartości pojedynczego wystąpienia o źródle danych, takich jak:Retrieve a singleton value about the source data, such as:

    • Liczba elementów, które odpowiadają określony warunek.The number of elements that match a certain condition.

    • Element, który ma największą lub najmniejszą wartość.The element that has the greatest or least value.

    • Pierwszy element, który dopasowuje warunek lub Suma wartości określonej w określonym zestawie elementów.The first element that matches a condition, or the sum of particular values in a specified set of elements. Na przykład, następujące zapytanie zwraca liczbę wyniki większy niż 80 z scores tablicy liczb całkowitych:For example, the following query returns the number of scores greater than 80 from the scores integer array:

      int highScoreCount =
          (from score in scores
           where score > 80
           select score)
           .Count();
      

      W poprzednim przykładzie, zwróć uwagę na użycie nawiasów wokół wyrażenia zapytania przed wywołaniem do Count metody.In the previous example, note the use of parentheses around the query expression before the call to the Count method. Można to również wyrazić przy użyciu nowej zmiennej do przechowywania konkretnego wyniku.You can also express this by using a new variable to store the concrete result. Ta technika jest bardziej czytelny, ponieważ zmienna, która przechowuje zapytanie utrzymuje oddzielnie od zapytania, które zapisuje wynik.This technique is more readable because it keeps the variable that stores the query separate from the query that stores a result.

      IEnumerable<int> highScoresQuery3 =
          from score in scores
          where score > 80
          select score;
      
      int scoreCount = highScoresQuery3.Count();
      

W poprzednim przykładzie zapytanie jest wykonywane w wywołaniu Count, ponieważ Count musi iterację w wynikach w celu ustalenia liczby elementów zwracanych przez highScoresQuery.In the previous example, the query is executed in the call to Count, because Count must iterate over the results in order to determine the number of elements returned by highScoresQuery.

Co to jest wyrażenie zapytania?What is a query expression?

A wyrażeniu zapytania jest zapytaniem wyrażone w składni zapytań.A query expression is a query expressed in query syntax. Wyrażenie kwerendy jest staje się konstrukcją języka.A query expression is a first-class language construct. Jest tak jak dowolne inne wyrażenie i mogą być używane w dowolnym kontekście, w którym wyrażenie języka C# jest poprawna.It is just like any other expression and can be used in any context in which a C# expression is valid. Wyrażenie zapytania zawiera zestaw klauzul napisane w składni deklaratywnej podobne do bazy danych SQL lub XQuery.A query expression consists of a set of clauses written in a declarative syntax similar to SQL or XQuery. Każdej klauzuli z kolei zawiera jeden lub więcej wyrażeń języka C# i wyrażenia te same jest wyrażenie zapytania lub zawiera wyrażenie zapytania.Each clause in turn contains one or more C# expressions, and these expressions may themselves be either a query expression or contain a query expression.

Wyrażenie zapytania musi zaczynać się od z klauzuli i musi kończyć się znakiem wybierz lub grupy klauzuli.A query expression must begin with a from clause and must end with a select or group clause. Między pierwszą from klauzuli i ostatnią select lub group klauzuli może zawierać co najmniej jedną z klauzul opcjonalne: gdzie, orderby, sprzężenia , umożliwiają i nawet dodatkowe z klauzul.Between the first from clause and the last select or group clause, it can contain one or more of these optional clauses: where, orderby, join, let and even additional from clauses. Można również użyć do — słowo kluczowe, aby umożliwić wynik join lub group klauzula, która będzie służyć jako źródło dla klauzule dodatkowe kwerendy w jednym wyrażeniu zapytania.You can also use the into keyword to enable the result of a join or group clause to serve as the source for additional query clauses in the same query expression.

Zmienna zapytaniaQuery variable

W programie LINQ, zmienna zapytania jest jakakolwiek zmienna, która przechowuje zapytania zamiast wyniki zapytania.In LINQ, a query variable is any variable that stores a query instead of the results of a query. Dokładniej mówiąc, zmienna zapytania jest zawsze typem wyliczalny, który powoduje wygenerowanie sekwencji elementów, gdy jest powtarzana w foreach instrukcji lub bezpośrednie wywołanie do jego IEnumerator.MoveNext metody.More specifically, a query variable is always an enumerable type that will produce a sequence of elements when it is iterated over in a foreach statement or a direct call to its IEnumerator.MoveNext method.

Poniższy przykład kodu pokazuje wyrażenie prostego zapytania z jednego źródła danych, jedną klauzulę filtrowania, jedną klauzulę szeregowania i nie przekształcania elementy źródłowe.The following code example shows a simple query expression with one data source, one filtering clause, one ordering clause, and no transformation of the source elements. select Klauzuli kończy się zapytania.The select clause ends the query.

static void Main()
{
    // Data source.
    int[] scores = { 90, 71, 82, 93, 75, 82 };

    // Query Expression.
    IEnumerable<int> scoreQuery = //query variable
        from score in scores //required
        where score > 80 // optional
        orderby score descending // optional
        select score; //must end with select or group

    // Execute the query to produce the results
    foreach (int testScore in scoreQuery)
    {
        Console.WriteLine(testScore);
    }                  
}
// Outputs: 93 90 82 82      

W poprzednim przykładzie scoreQuery jest zmienna zapytania którego jest czasami określane jako po prostu zapytania.In the previous example, scoreQuery is a query variable, which is sometimes referred to as just a query. Zmienna kwerendy przechowuje nie danych rzeczywisty wynik, który jest generowany w foreach pętli.The query variable stores no actual result data, which is produced in the foreach loop. I kiedy foreach wykonaniu instrukcji, wyniki zapytania nie są zwracane przez zmienna zapytania scoreQuery.And when the foreach statement executes, the query results are not returned through the query variable scoreQuery. Przeciwnie, są zwracane za pośrednictwem zmiennej iteracji testScore.Rather, they are returned through the iteration variable testScore. scoreQuery Zmiennej może być postanowiliśmy na sekundę foreach pętli.The scoreQuery variable can be iterated in a second foreach loop. Te same wyniki powoduje wygenerowanie tak długo, jak ten plik ani źródła danych został zmodyfikowany.It will produce the same results as long as neither it nor the data source has been modified.

Zmienna zapytania mogą być przechowywane zapytania, które są jest wyrażone w składni zapytań lub składnia metody lub kombinacji obu.A query variable may store a query that is expressed in query syntax or method syntax, or a combination of the two. W poniższych przykładach zarówno queryMajorCities i queryMajorCities2 zmiennych kwerendy:In the following examples, both queryMajorCities and queryMajorCities2 are query variables:

//Query syntax
IEnumerable<City> queryMajorCities =
    from city in cities
    where city.Population > 100000
    select city;


// Method-based syntax
IEnumerable<City> queryMajorCities2 = cities.Where(c => c.Population > 100000);

Z drugiej strony dwa poniższe przykłady pokazują zmiennych, które nie są zmiennych kwerendy, mimo że każdy jest inicjowany za pomocą zapytania.On the other hand, the following two examples show variables that are not query variables even though each is initialized with a query. Nie są one zmiennych kwerendy, ponieważ są przechowywane wyniki:They are not query variables because they store results:

int highestScore =
    (from score in scores
     select score)
    .Max();

// or split the expression
IEnumerable<int> scoreQuery =
    from score in scores
    select score;

int highScore = scoreQuery.Max();
// the following returns the same result
int highScore = scores.Max();

List<City> largeCitiesList =
    (from country in countries
     from city in country.Cities
     where city.Population > 10000
     select city)
       .ToList();

// or split the expression
IEnumerable<City> largeCitiesQuery =
    from country in countries
    from city in country.Cities
    where city.Population > 10000
    select city;

List<City> largeCitiesList2 = largeCitiesQuery.ToList();

Aby uzyskać więcej informacji o różnych sposobach express zapytań, zobacz składnia zapytania i metody w technologii LINQ.For more information about the different ways to express queries, see Query syntax and method syntax in LINQ.

Jawne i niejawne, wpisując zmiennych zapytaniaExplicit and implicit typing of query variables

Ta dokumentacja zawiera zazwyczaj jawnego typu zmiennej zapytania aby pokazać relację typ zmiennej zapytania i klauzuli select.This documentation usually provides the explicit type of the query variable in order to show the type relationship between the query variable and the select clause. Jednak możesz również użyć var — słowo kluczowe, aby poinstruować kompilator wywnioskuje typ zmiennej zapytania (lub dowolnej zmiennej lokalnej) w czasie kompilacji.However, you can also use the var keyword to instruct the compiler to infer the type of a query variable (or any other local variable) at compile time. Na przykład przykład zapytania, które zostało przedstawione wcześniej w tym temacie mogą być wyrażone przy użyciu niejawnego wpisywania:For example, the query example that was shown previously in this topic can also be expressed by using implicit typing:

// Use of var is optional here and in all queries.
// queryCities is an IEnumerable<City> just as 
// when it is explicitly typed.
var queryCities =
    from city in cities
    where city.Population > 100000
    select city;

Aby uzyskać więcej informacji, zobacz niejawnie wpisane zmienne lokalne i relacje typów w składniku LINQ zapytania operacje.For more information, see Implicitly typed local variables and Type relationships in LINQ query operations.

Uruchamianie wyrażenia zapytaniaStarting a query expression

Wyrażenie zapytania musi zaczynać się od from klauzuli.A query expression must begin with a from clause. Określa źródło danych, wraz z zmiennej zakresu.It specifies a data source together with a range variable. Zmienna zakresu reprezentuje każdy element w sekwencji źródłowej, jak linia sekwencji źródłowej.The range variable represents each successive element in the source sequence as the source sequence is being traversed. Zmienna zakresu jest silnie typizowane w oparciu o typ elementów w źródle danych.The range variable is strongly typed based on the type of elements in the data source. W poniższym przykładzie ponieważ countries jest tablicą Country obiektów, jako również jest wpisana zmienna zakresu Country.In the following example, because countries is an array of Country objects, the range variable is also typed as Country. Ponieważ zmienna zakresu zdecydowanie jest wpisane, można użyć operatora kropki wszystkie dostępne elementy członkowskie tego typu dostępu do.Because the range variable is strongly typed, you can use the dot operator to access any available members of the type.

IEnumerable<Country> countryAreaQuery =
    from country in countries
    where country.Area > 500000 //sq km
    select country;

Zmienna zakresu znajduje się w zakresie aż zapytanie zostanie zakończone, przy użyciu średnika lub za pomocą kontynuacji klauzuli.The range variable is in scope until the query is exited either with a semicolon or with a continuation clause.

Wyrażenie zapytania może zawierać więcej niż jednego from klauzul.A query expression may contain multiple from clauses. Użyj dodatkowych from klauzule podczas każdego elementu w sekwencji źródłowej jest kolekcją lub zawiera kolekcję.Use additional from clauses when each element in the source sequence is itself a collection or contains a collection. Na przykład załóżmy, że masz kolekcję Country obiektów, z których każdy zawiera zbiór City obiektów o nazwie Cities.For example, assume that you have a collection of Country objects, each of which contains a collection of City objects named Cities. Aby wykonać zapytanie City obiektów w każdym Country, użyj dwóch from klauzul, jak pokazano poniżej:To query the City objects in each Country, use two from clauses as shown here:

IEnumerable<City> cityQuery =
    from country in countries
    from city in country.Cities
    where city.Population > 10000
    select city;

Aby uzyskać więcej informacji, zobacz klauzuli from.For more information, see from clause.

Zakończenie wyrażenia zapytaniaEnding a query expression

Wyrażenie zapytania musi kończyć się albo group klauzuli lub select klauzuli.A query expression must end with either a group clause or a select clause.

group — Klauzulagroup clause

Użyj group klauzuli, która generuje sekwencję grupy organizowane według klucza, który określisz.Use the group clause to produce a sequence of groups organized by a key that you specify. Klucz może być dowolnego typu danych.The key can be any data type. Na przykład, następujące zapytanie powoduje utworzenie sekwencji grupy, która zawiera co najmniej jeden Country obiektów i którego klucza char wartość.For example, the following query creates a sequence of groups that contains one or more Country objects and whose key is a char value.

var queryCountryGroups =
    from country in countries
    group country by country.Name[0];

Aby uzyskać więcej informacji na temat grupowania, zobacz group — klauzula.For more information about grouping, see group clause.

select — Klauzulaselect clause

Użyj select klauzuli do tworzenia innych typów sekwencji.Use the select clause to produce all other types of sequences. Prosty select klauzuli po prostu tworzy sekwencję tego samego typu obiekty jako obiekty, które są zawarte w źródle danych.A simple select clause just produces a sequence of the same type of objects as the objects that are contained in the data source. W tym przykładzie źródło danych zawiera Country obiektów.In this example, the data source contains Country objects. orderby Klauzuli sortuje tylko elementy do nowego zamówienia i select klauzuli wytwarza sekwencję zmieniona kolejność Country obiektów.The orderby clause just sorts the elements into a new order and the select clause produces a sequence of the reordered Country objects.

IEnumerable<Country> sortedQuery =
    from country in countries
    orderby country.Area
    select country;

select Klauzuli może służyć do przekształcania danych źródłowych sekwencji nowych typów.The select clause can be used to transform source data into sequences of new types. Ta transformacja jest również określany projekcji.This transformation is also named a projection. W poniższym przykładzie select klauzuli projektów sekwencję typy anonimowe, która zawiera tylko podzbiór pól w oryginalnym elemencie.In the following example, the select clause projects a sequence of anonymous types which contains only a subset of the fields in the original element. Należy pamiętać, że nowe obiekty są inicjowane za pomocą inicjatora obiektów.Note that the new objects are initialized by using an object initializer.

// Here var is required because the query
// produces an anonymous type.
var queryNameAndPop =
    from country in countries
    select new { Name = country.Name, Pop = country.Population };

Aby uzyskać więcej informacji na temat wszystkich metod, select można używać klauzuli przetwarzają dane źródłowe, zobacz klauzuli select.For more information about all the ways that a select clause can be used to transform source data, see select clause.

Kontynuacje za pomocą "do"Continuations with "into"

Możesz użyć into — słowo kluczowe w select lub group klauzuli można utworzyć tymczasowego identyfikatora, która przechowuje zapytanie.You can use the into keyword in a select or group clause to create a temporary identifier that stores a query. W tym przypadku należy wykonać dodatkowe operacje w zapytaniu po grupowanie lub wybierz operację.Do this when you must perform additional query operations on a query after a grouping or select operation. W poniższym przykładzie countries są pogrupowane według populacji w zakresach 10 milionów.In the following example countries are grouped according to population in ranges of 10 million. Po tych grup zostaną utworzone, dodatkowe klauzul filtru się niektóre grupy, a następnie do sortowania grupy w kolejności rosnącej kolejności.After these groups are created, additional clauses filter out some groups, and then to sort the groups in ascending order. Aby wykonać te operacje dodatkowe, kontynuacja reprezentowany przez countryGroup jest wymagana.To perform those additional operations, the continuation represented by countryGroup is required.

// percentileQuery is an IEnumerable<IGrouping<int, Country>>
var percentileQuery =
    from country in countries
    let percentile = (int) country.Population / 10_000_000
    group country by percentile into countryGroup
    where countryGroup.Key >= 20
    orderby countryGroup.Key
    select countryGroup;

// grouping is an IGrouping<int, Country>
foreach (var grouping in percentileQuery)
{
    Console.WriteLine(grouping.Key);
    foreach (var country in grouping)
        Console.WriteLine(country.Name + ":" + country.Population);
}

Aby uzyskać więcej informacji, zobacz do.For more information, see into.

Filtrowanie, porządkowanie i dołączaniaFiltering, ordering, and joining

Między rozpoczęciem from klauzula i zakończenie select lub group klauzuli, inne klauzule (where, join, orderby, from, let) są opcjonalne.Between the starting from clause, and the ending select or group clause, all other clauses (where, join, orderby, from, let) are optional. Dowolne opcjonalne klauzule mogą być używane zero lub wiele razy w treść zapytania.Any of the optional clauses may be used zero times or multiple times in a query body.

Klauzula wherewhere clause

Użyj where klauzulę, aby odfiltrować elementy ze źródła danych oparte na co najmniej jednego wyrażenia predykatu.Use the where clause to filter out elements from the source data based on one or more predicate expressions. where Klauzula w poniższym przykładzie zawiera jeden predykat z dwóch warunków.The where clause in the following example has one predicate with two conditions.

IEnumerable<City> queryCityPop =
    from city in cities
    where city.Population < 200000 && city.Population > 100000
    select city;

Aby uzyskać więcej informacji, zobacz gdzie klauzula.For more information, see where clause.

Klauzula orderbyorderby clause

Użyj orderby klauzulę, aby posortować wyniki w kolejności rosnącej lub malejącej.Use the orderby clause to sort the results in either ascending or descending order. Można również określić, pomocniczej sortowania.You can also specify secondary sort orders. Poniższy przykład sortuje podstawowego country obiektów przy użyciu Area właściwości.The following example performs a primary sort on the country objects by using the Area property. Następnie wykonuje dodatkowej sortowanie za pomocą Population właściwości.It then performs a secondary sort by using the Population property.

IEnumerable<Country> querySortedCountries =
    from country in countries
    orderby country.Area, country.Population descending
    select country;

ascending — Słowo kluczowe jest opcjonalny; jest domyślny porządek sortowania, jeśli określono żadnej kolejności.The ascending keyword is optional; it is the default sort order if no order is specified. Aby uzyskać więcej informacji, zobacz klauzuli orderby.For more information, see orderby clause.

Klauzula joinjoin clause

Użyj join klauzuli, aby skojarzyć i/lub połączyć elementy z jednego źródła danych z elementów z innego źródła danych oparte na porównanie równości pomiędzy kluczami określony w każdym elemencie.Use the join clause to associate and/or combine elements from one data source with elements from another data source based on an equality comparison between specified keys in each element. W programie LINQ sprzężenia operacje są wykonywane w sekwencji, której elementy są różnych typów obiektów.In LINQ, join operations are performed on sequences of objects whose elements are different types. Po dołączeniu dwóch sekwencji, należy użyć select lub group instrukcję, aby określić który element do przechowywania w sekwencji wyjścia.After you have joined two sequences, you must use a select or group statement to specify which element to store in the output sequence. Można również użyć typu anonimowego do łączenia z każdego zestawu powiązanych elementów właściwości w nowy typ sekwencji wyjścia.You can also use an anonymous type to combine properties from each set of associated elements into a new type for the output sequence. W poniższym przykładzie prod obiekty, których Category właściwość odpowiada jednej z kategorii w categories tablicy ciągów.The following example associates prod objects whose Category property matches one of the categories in the categories string array. Produkty którego Category jest niezgodna z dowolnym ciągiem w categories są odfiltrowywane. select Instrukcji projektów nowego typu, którego właściwości są pobierane z obu cat i prod.Products whose Category does not match any string in categories are filtered out. The select statement projects a new type whose properties are taken from both cat and prod.

var categoryQuery =
    from cat in categories
    join prod in products on cat equals prod.Category
    select new { Category = cat, Name = prod.Name };

Sprzężenie grupy można również wykonać, przechowując wyniki join operacji w zmiennej tymczasowej, za pomocą do — słowo kluczowe.You can also perform a group join by storing the results of the join operation into a temporary variable by using the into keyword. Aby uzyskać więcej informacji, zobacz klauzuli join.For more information, see join clause.

Klauzula Letlet clause

Użyj let klauzuli, aby przechowywać wynik wyrażenia, takie jak wywołanie metody w nowej zmiennej zakresu.Use the let clause to store the result of an expression, such as a method call, in a new range variable. W poniższym przykładzie zmienna zakresu firstName przechowuje pierwszego elementu w tablicy ciągów, które są zwracane przez Split.In the following example, the range variable firstName stores the first element of the array of strings that is returned by Split.

string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" };
IEnumerable<string> queryFirstNames =
    from name in names
    let firstName = name.Split(' ')[0]
    select firstName;

foreach (string s in queryFirstNames)
    Console.Write(s + " ");
//Output: Svetlana Claire Sven Cesar

Aby uzyskać więcej informacji, zobacz let, klauzula.For more information, see let clause.

Podzapytania w wyrażeniu zapytaniaSubqueries in a query expression

Sam klauzula zapytania może zawierać wyrażenie zapytania, który jest czasem nazywany podzapytania.A query clause may itself contain a query expression, which is sometimes referred to as a subquery. Każdy podzapytania zaczyna się od jego własnej from klauzula, która nie musi wskazywać tego samego źródła danych w pierwszym from klauzuli.Each subquery starts with its own from clause that does not necessarily point to the same data source in the first from clause. Na przykład poniższe zapytanie pokazuje wyrażenie zapytania, które jest używane w instrukcji select, aby pobrać wyniki operacji grupowania.For example, the following query shows a query expression that is used in the select statement to retrieve the results of a grouping operation.

var queryGroupMax =
    from student in students
    group student by student.GradeLevel into studentGroup
    select new
    {
        Level = studentGroup.Key,
        HighestScore =
            (from student2 in studentGroup
             select student2.Scores.Average())
             .Max()
    };

Aby uzyskać więcej informacji, zobacz porady: wykonanie podzapytania w operacji grupowania.For more information, see How to: perform a subquery on a grouping operation.

Zobacz takżeSee also