Skip to content

Commit f43e8a2

Browse files
committed
Edit pass.
Grammar and edit pass.
1 parent 2f2fb74 commit f43e8a2

File tree

2 files changed

+18
-21
lines changed

2 files changed

+18
-21
lines changed

docs/csharp/linq/get-started/query-expression-basics.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ A query expression must begin with a [from](../../language-reference/keywords/fr
5252
In LINQ, a query variable is any variable that stores a *query* instead of the *results* of a query. More specifically, a query variable is always an enumerable type that produces a sequence of elements when iterated over in a `foreach` statement or a direct call to its <xref:System.Collections.IEnumerator.MoveNext?displayProperty=nameWithType> method.
5353

5454
> [!NOTE]
55-
> Examples in this article uses the following data source and sample data.
55+
> Examples in this article use the following data source and sample data.
5656
5757
:::code language="csharp" source="./snippets/SnippetApp/DataSources.cs" id="basics_datasource":::
5858

@@ -62,7 +62,7 @@ The following code example shows a simple query expression with one data source,
6262

6363
:::code language="csharp" source="./snippets/SnippetApp/Basics.cs" id="basics5":::
6464

65-
In the previous example, `scoreQuery` is a *query variable,* which is sometimes referred to as just a *query*. The query variable stores no actual result data, which is produced in the `foreach` loop. And when the `foreach` statement executes, the query results aren't returned through the query variable `scoreQuery`. Rather, they're returned through the iteration variable `testScore`. The `scoreQuery` variable can be iterated in a second `foreach` loop. It produces the same results as long as neither it nor the data source has been modified.
65+
In the previous example, `scoreQuery` is a *query variable,* which is sometimes referred to as just a *query*. The query variable stores no actual result data, which is produced in the `foreach` loop. And when the `foreach` statement executes, the query results aren't returned through the query variable `scoreQuery`. Rather, they're returned through the iteration variable `testScore`. The `scoreQuery` variable can be iterated in a second `foreach` loop. It produces the same results as long as neither it nor the data source was modified.
6666

6767
A query variable might store a query that is expressed in query syntax or method syntax, or a combination of the two. In the following examples, both `queryMajorCities` and `queryMajorCities2` are query variables:
6868

@@ -100,7 +100,7 @@ For more information, see [from clause](../../language-reference/keywords/from-c
100100

101101
A query expression must end with either a `group` clause or a `select` clause.
102102

103-
#### group clause
103+
#### The group clause
104104

105105
Use the `group` clause to produce a sequence of groups organized by a key that you specify. The key can be any data type. For example, the following query creates a sequence of groups that contains one or more `Country` objects and whose key is a `char` type with value being the first letter of countries' names.
106106

@@ -134,31 +134,31 @@ For more information, see [into](../../language-reference/keywords/into.md).
134134

135135
Between the starting `from` clause, and the ending `select` or `group` clause, all other clauses (`where`, `join`, `orderby`, `from`, `let`) are optional. Any of the optional clauses might be used zero times or multiple times in a query body.
136136

137-
#### where clause
137+
#### The where clause
138138

139139
Use the `where` clause to filter out elements from the source data based on one or more predicate expressions. The `where` clause in the following example has one predicate with two conditions.
140140

141141
:::code language="csharp" source="./snippets/SnippetApp/Basics.cs" id="basics15":::
142142

143143
For more information, see [where clause](../../language-reference/keywords/where-clause.md).
144144

145-
#### orderby clause
145+
#### The orderby clause
146146

147147
Use the `orderby` clause to sort the results in either ascending or descending order. You can also specify secondary sort orders. The following example performs a primary sort on the `country` objects by using the `Area` property. It then performs a secondary sort by using the `Population` property.
148148

149149
:::code language="csharp" source="./snippets/SnippetApp/Basics.cs" id="basics16":::
150150

151151
The `ascending` keyword is optional; it's the default sort order if no order is specified. For more information, see [orderby clause](../../language-reference/keywords/orderby-clause.md).
152152

153-
#### join clause
153+
#### The join clause
154154

155155
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, join operations are performed on sequences of objects whose elements are different types. After you join two sequences, you must use a `select` or `group` statement to specify which element to store in the output sequence. You can also use an anonymous type to combine properties from each set of associated elements into a new type for the output sequence. The following example associates `prod` objects whose `Category` property matches one of the categories in the `categories` string array. Products whose `Category` doesn't match any string in `categories` are filtered out. The `select` statement projects a new type whose properties are taken from both `cat` and `prod`.
156156

157157
:::code language="csharp" source="./snippets/SnippetApp/Basics.cs" id="basics17":::
158158

159159
You can also perform a group join by storing the results of the `join` operation into a temporary variable by using the [into](../../language-reference/keywords/into.md) keyword. For more information, see [join clause](../../language-reference/keywords/join-clause.md).
160160

161-
#### let clause
161+
#### The let clause
162162

163163
Use the `let` clause to store the result of an expression, such as a method call, in a new range variable. In the following example, the range variable `firstName` stores the first element of the array of strings returned by `Split`.
164164

docs/csharp/linq/get-started/write-linq-queries.md

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ms.date: 01/16/2025
55
---
66
# Write C# LINQ queries to query data
77

8-
Most queries in the introductory Language Integrated Query (LINQ) documentation are written by using the LINQ declarative query syntax. However, the query syntax must be translated into method calls for the .NET common language runtime (CLR) when the code is compiled. These method calls invoke the standard query operators, which have names such as `Where`, `Select`, `GroupBy`, `Join`, `Max`, and `Average`. You can call them directly by using method syntax instead of query syntax.
8+
Most queries in the introductory Language Integrated Query (LINQ) documentation are written by using the LINQ declarative query syntax. The C# compiler translates query syntax into method calls. These method calls implement the standard query operators, which have names such as `Where`, `Select`, `GroupBy`, `Join`, `Max`, and `Average`. You can call them directly by using method syntax instead of query syntax.
99

1010
Query syntax and method syntax are semantically identical, but query syntax is often simpler and easier to read. Some queries must be expressed as method calls. For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition. You also must use a method call for a query that retrieves the element that has the maximum value in a source sequence. The reference documentation for the standard query operators in the <xref:System.Linq> namespace generally uses method syntax. You should become familiar with how to use method syntax in queries and in query expressions themselves.
1111

@@ -15,30 +15,28 @@ The following example shows a simple *query expression* and the semantically equ
1515

1616
:::code language="csharp" source="./snippets/SnippetApp/WriteLinqQueries.cs" id="MethodSyntax":::
1717

18-
The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: <xref:System.Collections.Generic.IEnumerable%601>.
18+
The output from the two examples is identical. The type of the query variable is the same in both forms: <xref:System.Collections.Generic.IEnumerable%601>.
1919

20-
To understand the method-based query, let's examine it more closely. On the right side of the expression, notice that the `where` clause is now expressed as an instance method on the `numbers` object, which has a type of `IEnumerable<int>`. If you're familiar with the generic <xref:System.Collections.Generic.IEnumerable%601> interface, you know that it doesn't have a `Where` method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you see not only a `Where` method, but many other methods such as `Select`, `SelectMany`, `Join`, and `Orderby`. These methods implement the standard query operators.
20+
On the right side of the expression, notice that the `where` clause is now expressed as an instance method on the `numbers` object, which has a type of `IEnumerable<int>`. If you're familiar with the generic <xref:System.Collections.Generic.IEnumerable%601> interface, you know that it doesn't have a `Where` method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you see not only a `Where` method, but many other methods such as `Select`, `SelectMany`, `Join`, and `Orderby`. These methods implement the standard query operators.
2121

2222
![Screenshot showing all the standard query operators in Intellisense.](./media/write-linq-queries/standard-query-operators.png)
2323

24-
Although it looks as if <xref:System.Collections.Generic.IEnumerable%601> includes more methods, it doesn't. The standard query operators are implemented as *extension methods*. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend <xref:System.Collections.Generic.IEnumerable%601> and that is why you can write `numbers.Where(...)`.
25-
26-
To use extension methods, you bring them into scope with `using` directives. From your application's point of view, an extension method and a regular instance method are the same.
24+
Although it looks as if <xref:System.Collections.Generic.IEnumerable%601> includes more methods, it doesn't. The standard query operators are implemented as *extension methods*. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend <xref:System.Collections.Generic.IEnumerable%601> and that is why you can write `numbers.Where(...)`. You bring extensions into scope with `using` directives before calling them.
2725

2826
For more information about extension methods, see [Extension Methods](../../programming-guide/classes-and-structs/extension-methods.md). For more information about standard query operators, see [Standard Query Operators Overview (C#)](../standard-query-operators/index.md). Some LINQ providers, such as [Entity Framework](/ef/core/) and LINQ to XML, implement their own standard query operators and extension methods for other types besides <xref:System.Collections.Generic.IEnumerable%601>.
2927

3028
## Lambda expressions
3129

32-
In the previous example, notice that the conditional expression (`num % 2 == 0`) is passed as an in-line argument to the <xref:System.Linq.Enumerable.Where%2A?displayProperty=nameWithType> method: `Where(num => num % 2 == 0).` This inline expression is a [lambda expression](../../language-reference/operators/lambda-expressions.md). It's a convenient way to write code that would otherwise have to be written in more cumbersome form. The `num` on the left of the operator is the input variable, which corresponds to `num` in the query expression. The compiler can infer the type of `num` because it knows that `numbers` is a generic <xref:System.Collections.Generic.IEnumerable%601> type. The body of the lambda is just the same as the expression in query syntax or in any other C# expression or statement. It can include method calls and other complex logic. The return value is just the expression result. Certain queries can only be expressed in method syntax and some of those require lambda expressions. Lambda expressions are a powerful and flexible tool in your LINQ toolbox.
30+
In the preceding example, the conditional expression (`num % 2 == 0`) is passed as an in-line argument to the <xref:System.Linq.Enumerable.Where%2A?displayProperty=nameWithType> method: `Where(num => num % 2 == 0).` This inline expression is a [lambda expression](../../language-reference/operators/lambda-expressions.md). It's a convenient way to write code that would otherwise have to be written in more cumbersome form. The `num` on the left of the operator is the input variable, which corresponds to `num` in the query expression. The compiler can infer the type of `num` because it knows that `numbers` is a generic <xref:System.Collections.Generic.IEnumerable%601> type. The body of the lambda is the same as the expression in query syntax or in any other C# expression or statement. It can include method calls and other complex logic. The return value is the expression result. Certain queries can only be expressed in method syntax and some of those queries require lambda expressions. Lambda expressions are a powerful and flexible tool in your LINQ toolbox.
3331

3432
## Composability of queries
3533

36-
In the previous code example, the <xref:System.Linq.Enumerable.OrderBy%2A?displayProperty=nameWithType> method is invoked by using the dot operator on the call to `Where`. `Where` produces a filtered sequence, and then `Orderby` sorts the sequence produced by `Where`. Because queries return an `IEnumerable`, you compose them in method syntax by chaining the method calls together. The compiler does this composition when you write queries using query syntax. Because a query variable doesn't store the results of the query, you can modify it or use it as the basis for a new query at any time, even after you execute it.
34+
In the preceding code example, the <xref:System.Linq.Enumerable.OrderBy%2A?displayProperty=nameWithType> method is invoked by using the dot operator on the call to `Where`. `Where` produces a filtered sequence, and then `Orderby` sorts the sequence produced by `Where`. Because queries return an `IEnumerable`, you compose them in method syntax by chaining the method calls together. The compiler does this composition when you write queries using query syntax. Because a query variable doesn't store the results of the query, you can modify it or use it as the basis for a new query at any time, even after you execute it.
3735

38-
The following examples demonstrate some simple LINQ queries by using each approach listed previously.
36+
The following examples demonstrate some basic LINQ queries by using each approach listed previously.
3937

4038
> [!NOTE]
41-
> These queries operate on simple in-memory collections; however, the basic syntax is identical to that used in LINQ to Entities and LINQ to XML.
39+
> These queries operate on in-memory collections; however, the syntax is identical to that used in LINQ to Entities and LINQ to XML.
4240
4341
## Example - Query syntax
4442

@@ -54,7 +52,7 @@ In each previous example, the queries don't actually execute until you iterate o
5452

5553
## Example - Method syntax
5654

57-
Some query operations must be expressed as a method call. The most common such methods are those methods that return singleton numeric values, such as <xref:System.Linq.Enumerable.Sum%2A>, <xref:System.Linq.Enumerable.Max%2A>, <xref:System.Linq.Enumerable.Min%2A>, <xref:System.Linq.Enumerable.Average%2A>, and so on. These methods must always be called last in any query because they return a single value and can't serve as the source for an extra query operation. The following example shows a method call in a query expression:
55+
Some query operations must be expressed as a method call. The most common such methods are those methods that return singleton numeric values, such as <xref:System.Linq.Enumerable.Sum%2A>, <xref:System.Linq.Enumerable.Max%2A>, <xref:System.Linq.Enumerable.Min%2A>, <xref:System.Linq.Enumerable.Average%2A>, and so on. These methods must always be called last in any query because they return a single value and can't serve as the source for an additional query operation. The following example shows a method call in a query expression:
5856

5957
:::code language="csharp" source="./snippets/SnippetApp/WriteLinqQueries.cs" id="write_linq_queries_2":::
6058

@@ -70,7 +68,7 @@ Each of the previous queries can be written by using implicit typing with [`var`
7068

7169
## Example - Mixed query and method syntax
7270

73-
This example shows how to use method syntax on the results of a query clause. Just enclose the query expression in parentheses, and then apply the dot operator and call the method. In the following example, query #7 returns a count of the numbers whose value is between 3 and 7. In general, however, it's better to use a second variable to store the result of the method call. In this manner, the query is less likely to be confused with the results of the query.
71+
This example shows how to use method syntax on the results of a query clause. Just enclose the query expression in parentheses, and then apply the dot operator and call the method. In the following example, query #7 returns a count of the numbers whose value is between 3 and 7.
7472

7573
:::code language="csharp" source="./snippets/SnippetApp/WriteLinqQueries.cs" id="write_linq_queries_5":::
7674

@@ -137,7 +135,7 @@ In each of the examples, the `equals` query keyword is used. You can also use [p
137135

138136
## Handle exceptions in query expressions
139137

140-
It's possible to call any method in the context of a query expression. Don't call any method in a query expression that can create a side effect such as modifying the contents of the data source or throwing an exception. This example shows how to avoid raising exceptions when you call methods in a query expression without violating the general .NET guidelines on exception handling. Those guidelines state that it's acceptable to catch a specific exception when you understand why it's thrown in a given context. For more information, see [Best Practices for Exceptions](../../../standard/exceptions/best-practices-for-exceptions.md).
138+
It's possible to call any method in the context of a query expression. Don't call any method in a query expression that can create a side effect such as modifying the contents of the data source or throwing an exception. This example shows how to avoid raising exceptions when you call methods in a query expression without violating the general .NET guidelines on exception handling. Those guidelines state that it's acceptable to catch a specific exception when you understand why it was thrown in a given context. For more information, see [Best Practices for Exceptions](../../../standard/exceptions/best-practices-for-exceptions.md).
141139

142140
The final example shows how to handle those cases when you must throw an exception during execution of a query.
143141

@@ -157,7 +155,6 @@ Remember to catch whatever exception you expect to raise and/or do any necessary
157155

158156
## See also
159157

160-
- [Walkthrough: Writing Queries in C#](walkthrough-writing-queries-linq.md)
161158
- [where clause](../../language-reference/keywords/where-clause.md)
162159
- [Querying based on runtime state](../../advanced-topics/expression-trees/debugview-syntax.md)
163160
- <xref:System.Nullable%601>

0 commit comments

Comments
 (0)