Grundlagen zu AbfrageausdrückenQuery expression basics

Was ist eine Abfrage, und welche Funktion hat sie?What is a query and what does it do?

Eine Abfrage ist ein Satz von Anweisungen, der beschreibt, welche Daten aus einer bestimmten Datenquelle (oder Quellen) abgerufen werden sollen, und welche Form und Organisation die zurückgegebenen Daten haben sollen.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. Eine Abfrage unterscheidet sich von den Ergebnissen, die sie erzeugt.A query is distinct from the results that it produces.

Im Allgemeinen werden die Quelldaten logisch als Sequenz von Elementen der gleichen Art organisiert.Generally, the source data is organized logically as a sequence of elements of the same kind. Eine SQL-Datenbanktabelle enthält z.B. eine Sequenz von Zeilen.For example, a SQL database table contains a sequence of rows. In einer XML-Datei gibt es eine „Sequenz“ von XML-Elementen (auch wenn diese hierarchisch in einer Baumstruktur organisiert sind).In an XML file, there is a "sequence" of XML elements (although these are organized hierarchically in a tree structure). Eine Auflistung im Arbeitsspeicher enthält eine Sequenz von Objekten.An in-memory collection contains a sequence of objects.

Aus Sicht einer Anwendung ist der spezifische Typ und die Struktur der ursprünglichen Datenquelle nicht wichtig.From an application's viewpoint, the specific type and structure of the original source data is not important. Die Anwendung sieht die Quelldaten immer als eine IEnumerable<T>- oder IQueryable<T>-Auflistung an.The application always sees the source data as an IEnumerable<T> or IQueryable<T> collection. In LINQ to XML werden die Quelldaten z.B. als ein IEnumerable<XElement sichtbar gemacht.For example, in LINQ to XML, the source data is made visible as an IEnumerable<XElement>.

Wenn diese Quellsequenz vorliegt, kann eine Abfrage eine der folgenden drei Aktionen durchführen:Given this source sequence, a query may do one of three things:

  • Abrufen einer Teilmenge der Elemente zum Erstellen einer neuen Sequenz ohne die einzelnen Elemente zu verändern.Retrieve a subset of the elements to produce a new sequence without modifying the individual elements. Die Abfrage kann die zurückgegebenen Sequenzen dann auf verschiedene Arten sortieren oder gruppieren, wie im folgenden Beispiel gezeigt wird (Annahme: scores ist 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;
    
  • Abrufen einer Sequenz von Elementen wie im vorherigen Beispiel, aber mit Transformation der Elemente in einen neuen Objekttyp.Retrieve a sequence of elements as in the previous example but transform them to a new type of object. Eine Abfrage kann z.B. nur die Nachnamen aus bestimmten Kundendatensätzen in einer Datenquelle abrufen.For example, a query may retrieve only the last names from certain customer records in a data source. Sie kann möglicherweise auch den vollständigen Datensatz abrufen und ihn zum Erstellen eines anderen Objekttyps im Arbeitsspeicher oder sogar XML-Daten vor dem Generieren der endgültigen Ergebnissequenz verwenden.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. Im folgenden Beispiel wird eine Projektion von int in string veranschaulicht.The following example shows a projection from an int to a string. Beachten Sie den neuen Typ von highScoresQuery.Note the new type of highScoresQuery.

    IEnumerable<string> highScoresQuery2 =
        from score in scores
        where score > 80
        orderby score descending
        select String.Format("The score is {0}", score);
    
  • Abrufen eines Singleton-Werts zu den Quelldaten, z.B.:Retrieve a singleton value about the source data, such as:

    • Die Anzahl der Elemente, die eine bestimmte Bedingung erfüllenThe number of elements that match a certain condition.

    • Das Element, das den größten oder den niedrigsten Wert hatThe element that has the greatest or least value.

    • Das erste Element, das einer Bedingung entspricht oder die Summe bestimmter Werte in einer angegebenen Menge von ElementenThe first element that matches a condition, or the sum of particular values in a specified set of elements. Die folgende Abfrage gibt z.B. die Anzahl von Ergebnissen aus dem scores-Ganzzahlarray zurück, die höher als 80 sind: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();
    

    Beachten Sie im vorherigen Beispiel die Verwendung von Klammern um den Abfrageausdruck vor dem Aufruf der Count-Methode.In the previous example, note the use of parentheses around the query expression before the call to the Count method. Sie können dies auch mit einer neuen Variable ausdrücken, um das konkrete Ergebnis zu speichern.You can also express this by using a new variable to store the concrete result. Diese Technik ist besser lesbar, da die Variablen, die die Abfrage speichern, von der Abfrage getrennt sind, die ein Ergebnis speichert.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();
    

Im vorherigen Beispiel wird die Abfrage im Aufruf von Count ausgeführt, da Count die Ergebnisse durchlaufen muss, um die Anzahl der von highScoresQuery zurückgegebenen Elemente zu bestimmen.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.

Was ist ein Abfrageausdruck?What is a query expression?

Ein Abfrageausdruck ist eine in der Abfragesyntax ausgedrückte Abfrage.A query expression is a query expressed in query syntax. Ein Abfrageausdruck ist ein erstklassiges Sprachkonstrukt.A query expression is a first-class language construct. Er verhält sich wie jeder andere Ausdruck und kann in jedem Kontext verwendet werden, in dem ein C#-Ausdruck gültig ist.It is just like any other expression and can be used in any context in which a C# expression is valid. Ein Abfrageausdruck besteht aus einem Satz von in einer deklarativen Syntax geschriebenen Klauseln, ähnlich wie SQL oder XQuery.A query expression consists of a set of clauses written in a declarative syntax similar to SQL or XQuery. Jede Klausel umfasst wiederum einen oder mehrere C#-Ausdrücke. Diese Ausdrücke sind möglicherweise selbst Abfrageausdrücke oder enthalten einen Abfrageausdruck.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.

Ein Abfrageausdruck muss mit einer from-Klausel beginnen und mit einer select- oder group-Klausel enden.A query expression must begin with a from clause and must end with a select or group clause. Zwischen der ersten from-Klausel und der letzten select- oder group-Klausel kann ein Abfrageausdruck eine oder mehrere der folgenden optionalen Klauseln enthalten: where, orderby, join, let und sogar zusätzliche from-Klauseln.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. Sie können auch das Schlüsselwort into verwenden, um zuzulassen, das das Ergebnis einer join- oder group-Klausel als Quelle für zusätzliche Abfrageklauseln im selben Abfrageausdruck dient.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.

AbfragevariableQuery variable

In LINQ ist eine Abfragevariable eine beliebige Variable, die eine Abfrage anstatt des Ergebnisses einer Abfrage speichert.In LINQ, a query variable is any variable that stores a query instead of the results of a query. Genauer gesagt ist eine Abfragevariable immer ein Enumerable-Typ, der eine Sequenz von Elementen erzeugt, wenn er in einer foreach-Anweisung oder einem direkten Aufruf der IEnumerator.MoveNext-Methode durchlaufen wird.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.

Das folgende Codebeispiel zeigt einen einfachen Abfrageausdruck mit einer Datenquelle, einer Filtering-Klausel, einer Ordering-Klausel und ohne Transformationen der Quellelemente.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. Die Klausel select beendet die Abfrage.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      

Im vorherigen Beispiel ist scoreQuery eine Abfragevariable, die manchmal auch einfach als Abfrage bezeichnet wird.In the previous example, scoreQuery is a query variable, which is sometimes referred to as just a query. Die Abfragevariable speichert keine tatsächlichen Ergebnisdaten, die in der foreach-Schleife erzeugt werden.The query variable stores no actual result data, which is produced in the foreach loop. Wenn die foreach-Anweisung ausgeführt wird, werden die Ergebnisse der Abfrage nicht über die Abfragevariable scoreQuery zurückgegeben.And when the foreach statement executes, the query results are not returned through the query variable scoreQuery. Stattdessen werden sie über die Iterationsvariable testScore zurückgegeben.Rather, they are returned through the iteration variable testScore. Die scoreQuery-Variable kann in einer zweiten foreach-Schleife durchlaufen werden.The scoreQuery variable can be iterated in a second foreach loop. Die gleichen Ergebnisse werden erzeugt, solange weder die Variable noch die Datenquelle geändert wurde.It will produce the same results as long as neither it nor the data source has been modified.

Eine Abfragevariable kann eine Abfrage speichern, die in einer Abfragesyntax oder Methodensyntax oder einer Kombination aus beiden ausgedrückt wird.A query variable may store a query that is expressed in query syntax or method syntax, or a combination of the two. In den folgenden Beispielen sind sowohl queryMajorCities als auch queryMajorCities2 Abfragevariablen: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);

Andererseits zeigen die beiden nächsten Beispiele Variablen, die keine Abfragevariablen sind, obwohl beide mit einer Abfrage initialisiert werden.On the other hand, the following two examples show variables that are not query variables even though each is initialized with a query. Sie sind keine Abfragevariablen, da sie Ergebnisse speichern: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();

Weitere Informationen zu den verschiedenen Verfahren zum Ausdrücken von Abfragen finden Sie unter Query syntax and method syntax in LINQ (Abfragesyntax und Methodensyntax in LINQ).For more information about the different ways to express queries, see Query syntax and method syntax in LINQ.

Explizite und implizite Typisierung von AbfragevariablenExplicit and implicit typing of query variables

Diese Dokumentation enthält normalerweise den expliziten Typ der Abfragevariablen, um die Typbeziehung zwischen der Abfrage und der select-Klausel darzustellen.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. Sie können aber auch das Schlüsselwort var verwenden, um den Compiler anzuweisen, den Typ einer Abfragevariable (oder eine andere lokale Variable) zur Kompilierzeit abzuleiten.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. Das Beispiel einer Abfrage, das vorher in diesem Thema gezeigt wurde, kann beispielsweise auch durch implizierte Typisierung ausgedrückt werden: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;

Weitere Informationen finden Sie unter Implizit typisierte lokale Variablen und Type relationships in LINQ query operations (Typbeziehungen in LINQ-Abfragevorgängen).For more information, see Implicitly typed local variables and Type relationships in LINQ query operations.

Starten eines AbfrageausdrucksStarting a query expression

Ein Abfrageausdruck muss mit einer from-Klausel beginnen.A query expression must begin with a from clause. Er gibt eine Datenquelle zusammen mit einer Bereichsvariablen an.It specifies a data source together with a range variable. Die Bereichsvariable stellt jedes darauffolgende Element in der Quellsequenz dar, wenn das Quellelement durchsucht wird.The range variable represents each successive element in the source sequence as the source sequence is being traversed. Die Bereichsvariable ist, basierend auf den Typen des Elements in der Datenquelle, stark typisiert.The range variable is strongly typed based on the type of elements in the data source. Im folgenden Beispiel ist die Bereichsvariable auch als Country typisiert, da countries ein Array von Country-Objekten ist.In the following example, because countries is an array of Country objects, the range variable is also typed as Country. Da die Bereichsvariable stark typisiert ist, können Sie den Punktoperator verwenden, um auf verfügbare Member des Typs zuzugreifen.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;

Die Bereichsvariable befindet sich im Geltungsbereich, bis die Abfrage entweder mit einem Semikolon oder einer continuation-Klausel beendet wird.The range variable is in scope until the query is exited either with a semicolon or with a continuation clause.

Ein Abfrageausdruck enthält möglicherweise mehrere from-Klauseln.A query expression may contain multiple from clauses. Verwenden Sie zusätzliche from-Klauseln, wenn jedes Element in der Quellsequenz selbst eine Auflistung ist oder eine Auflistung enthält.Use additional from clauses when each element in the source sequence is itself a collection or contains a collection. Nehmen wir beispielsweise an, dass Sie über eine Auflistung von Country-Objekten verfügen, von der jedes eine Auflistung von City-Objekten mit dem Namen Cities enthält.For example, assume that you have a collection of Country objects, each of which contains a collection of City objects named Cities. Verwenden Sie zwei from-Klauseln, um die City-Objekte in jedem Country abzufragen, wie hier gezeigt: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;

Weitere Informationen finden Sie unter from-Klausel.For more information, see from clause.

Beenden eines AbfrageausdrucksEnding a query expression

Ein Abfrageausdruck muss entweder mit einer group- oder einer select-Klausel enden.A query expression must end with either a group clause or a select clause.

group-Klauselgroup clause

Verwenden Sie die group-Klausel, um eine Sequenz von Gruppen zu erzeugen, die von einem von Ihnen angegebenen Schüssel organisiert wird.Use the group clause to produce a sequence of groups organized by a key that you specify. Der Schlüssel kann ein beliebiger Datentyp sein.The key can be any data type. Die folgende Abfrage erstellt z.B. eine Sequenz von Gruppen, die ein oder mehrere Country-Objekte enthält und deren Schlüssel ein char-Wert ist.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];

Weitere Informationen zum Gruppieren finden Sie unter group-Klausel.For more information about grouping, see group clause.

select-Klauselselect clause

Verwenden Sie die select-Klausel, um alle anderen Typen von Sequenzen zu erzeugen.Use the select clause to produce all other types of sequences. Eine einfache select-Klausel erzeugt nur eine Sequenz von Objekten desselben Typs wie die Objekte, die in der Datenquelle enthalten sind.A simple select clause just produces a sequence of the same type of objects as the objects that are contained in the data source. In diesem Beispiel enthält die Datenquelle Country-Objekte.In this example, the data source contains Country objects. Die orderby-Klausel sortiert die Elemente in eine neue Reihenfolge, und die select-Klausel erzeugt eine Sequenz der neu angeordneten Country-Objekte.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;

Die select-Klausel kann zum Transformieren von Quelldaten in Sequenzen neuer Typen verwendet werden.The select clause can be used to transform source data into sequences of new types. Diese Transformation wird auch als Projektion bezeichnet.This transformation is also named a projection. Im folgenden Beispiel projiziertselect die -Klausel eine Sequenz anonymer Typen, die nur eine Teilmenge der Felder im originalen Element enthalten.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. Beachten Sie, dass die neuen Objekte mit einem Objektinitialisierer initialisiert werden.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 };

Weitere Informationen zu allen Verfahren, in denen eine select-Klausel zum Transformieren von Daten verwendet werden kann, finden Sie unter select-Klausel.For more information about all the ways that a select clause can be used to transform source data, see select clause.

Fortsetzungen mit „into“Continuations with "into"

Sie können das Schlüsselwort into in einer select- oder group-Klausel verwenden, um einen temporären Bezeichner zu erstellen, der eine Abfrage speichert.You can use the into keyword in a select or group clause to create a temporary identifier that stores a query. Dieses Vorgehen ist ratsam, wenn Sie zusätzliche Abfragevorgänge nach einem grouping- oder einem select-Vorgang auf eine Abfrage ausführen müssen.Do this when you must perform additional query operations on a query after a grouping or select operation. Im folgenden Beispiel werden countries gemäß der Bevölkerung in Bereiche von 10 Millionen gruppiert.In the following example countries are grouped according to population in ranges of 10 million. Nachdem diese Gruppen erstellt wurden, filtern zusätzliche Klauseln einige Gruppen heraus und sortieren die Gruppen dann in aufsteigender Reihenfolge.After these groups are created, additional clauses filter out some groups, and then to sort the groups in ascending order. Um diese zusätzlichen Vorgänge durchzuführen, wird die von countryGroup dargestellte Fortsetzung benötigt.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);
}

Weitere Informationen finden Sie unter into.For more information, see into.

Filtern, Sortieren und VerknüpfenFiltering, ordering, and joining

Zwischen der from-Klausel am Anfang und der select- oder group-Klausel am Ende sind alle anderen Klauseln (where, join, orderby, from, let) optional.Between the starting from clause, and the ending select or group clause, all other clauses (where, join, orderby, from, let) are optional. Eine der optionalen Klauseln kann entweder überhaupt nicht oder mehrfach in einem Abfragetext verwendet werden.Any of the optional clauses may be used zero times or multiple times in a query body.

where-Klauselwhere clause

Verwenden Sie die Klausel where zum Herausfiltern von Elementen aus den Quelldaten basierend auf einem oder mehreren Prädikatausdrücken.Use the where clause to filter out elements from the source data based on one or more predicate expressions. Im folgenden Beispiel verfügt die Klausel where über ein Prädikat mit zwei Bedingungen.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;

Weitere Informationen finden Sie unter where-Klausel.For more information, see where clause.

orderby-Klauselorderby clause

Verwenden Sie die orderby-Klausel zum Sortieren der Ergebnisse in auf- oder absteigender Reihenfolge.Use the orderby clause to sort the results in either ascending or descending order. Sie können auch eine sekundäre Sortierreihenfolge angeben.You can also specify secondary sort orders. Im folgenden Beispiel wird mit der Eigenschaft Area eine primäre Sortierung der country-Objekte durchgeführt.The following example performs a primary sort on the country objects by using the Area property. Anschließend wird eine sekundäre Sortierung mit der Eigenschaft Population durchgeführt.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;

Das Schlüsselwort ascending ist optional; wenn keine andere Reihenfolge angegeben ist, ist dies die Standardreihenfolge.The ascending keyword is optional; it is the default sort order if no order is specified. Weitere Informationen finden Sie unter orderby-Klausel.For more information, see orderby clause.

join-Klauseljoin clause

Verwenden Sie die join-Klausel zum Zuordnen und/oder Kombinieren von Elementen aus einer Datenquelle mit Elementen aus einer anderen Datenquelle basierend auf einem Gleichheitsvergleich zwischen angegebenen Schlüsseln in jedem Element.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. In LINQ werden Verknüpfungsvorgänge für Sequenzen von Objekten ausgeführt, deren Elemente unterschiedliche Typen haben.In LINQ, join operations are performed on sequences of objects whose elements are different types. Nachdem Sie zwei Segmente verknüpft haben, müssen Sie eine select- oder group-Anweisung verwenden, um anzugeben, welches Element in der Ausgabesequenz gespeichert werden soll.After you have joined two sequences, you must use a select or group statement to specify which element to store in the output sequence. Sie können auch einen anonymen Typ verwenden, um Eigenschaften aus jedem Satz der zugewiesenen Elemente in einem neuen Typ für die Ausgabesequenz zu kombinieren.You can also use an anonymous type to combine properties from each set of associated elements into a new type for the output sequence. Im folgenden Beispiel werden prod-Objekte, deren Category-Eigenschaft einer der Kategorien im categories-Zeichenfolgearray entspricht, zugewiesen.The following example associates prod objects whose Category property matches one of the categories in the categories string array. Produkte, deren Category keiner Zeichenfolge in categories entspricht, werden herausgefiltert. Die select-Anweisung projiziert einen neuen Typ, dessen Eigenschaften aus cat und prod stammen.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 };

Sie können auch eine Gruppenverknüpfung durchführen, indem Sie die Ergebnisse des join-Vorgangs mithilfe des Schlüsselworts into in eine temporäre Variable speichern.You can also perform a group join by storing the results of the join operation into a temporary variable by using the into keyword. Weitere Informationen finden Sie unter join-Klausel.For more information, see join clause.

let-Klausellet clause

Verwenden Sie die let-Klausel zum Speichern der Ergebnisse eines Ausdrucks, z.B. eines Methodenaufrufs, in einer neuen Bereichsvariable.Use the let clause to store the result of an expression, such as a method call, in a new range variable. Im folgenden Beispiel speichert die Bereichsvariable firstName das erste Elemente eines Arrays von Zeichenfolgen, das von Split zurückgegeben wird.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

Weitere Informationen finden Sie unter let-Klausel.For more information, see let clause.

Unterabfragen in einem AbfrageausdruckSubqueries in a query expression

Ein Abfrageausdruck selbst kann eine Abfrageklausel enthalten, die manchmal als Unterabfrage bezeichnet wird.A query clause may itself contain a query expression, which is sometimes referred to as a subquery. Jede Unterabfrage beginnt mit ihrer eigenen from-Klausel, die nicht unbedingt auf die gleiche Datenquelle in der ersten from-Klausel zeigt.Each subquery starts with its own from clause that does not necessarily point to the same data source in the first from clause. Die folgende Abfrage zeigt z.B. einen Abfrageausdruck, der in der Select-Anweisung zum Abrufen der Ergebnisse eines Gruppierungsvorganges verwendet wird.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()
    };

Weitere Informationen finden Sie unter Gewusst wie: Ausführen einer Unterabfrage für eine Gruppierungsoperation (C#-Programmierhandbuch).For more information, see How to: perform a subquery on a grouping operation.

Siehe auchSee Also

C#-ProgrammierhandbuchC# programming guide
LINQ-AbfrageausdrückeLINQ query expressions
Abfrageschlüsselwörter (LINQ)Query keywords (LINQ)
Übersicht über die StandardabfrageoperatorenStandard query operators overview