C#idiomatic C#
walkthrough-writing-queries-linqcsharp/linq/get-started

LINQ

Tutorial: Write queries in C# using language integrated query (LINQ)

This walkthrough shows how C# language features are used in LINQ query expressions.

  • page csharp/linq/get-started/walkthrough-writing-queries-linq
  • updated 04/22/2024

In this tutorial, you create a data source and write several LINQ queries. You can experiment with the query expressions and see the differences in the results. This walkthrough demonstrates the C# language features that are used to write LINQ query expressions. You can follow along and build the app and experiment with the queries yourself. This article assumes you've installed the latest .NET SDK. If not, go to the .NET Downloads page and install the latest version on your machine.

First, create the application. From the console, type the following command:

dotnetcli
dotnet new console -o WalkthroughWritingLinqQueries

Or, if you prefer Visual Studio, create a new console application named WalkthroughWritingLinqQueries.

Create an in-memory data source

The first step is to create a data source for your queries. The data source for the queries is a simple list of Student records. Each Student record has a first name, family name, and an array of integers that represents their test scores in the class. Add a new file named students.cs, and copy the following code into that file:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/StudentDataSource.cs

csharp
namespace WalkthroughWritingLinqQueries;

public record Student(string First, string Last, int ID, int[] Scores);

Note the following characteristics:

  • The Student record consists of automatically implemented properties.
  • Each student in the list is initialized with the primary constructor.
  • The sequence of scores for each student is initialized with a primary constructor.

Next, create a sequence of Student records that serves as the source of this query. Open Program.cs, and remove the following boilerplate code:

csharp
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

Replace it with the following code that creates a sequence of Student records:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csCreateSequence

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}
  • The sequence of students is initialized with a collection expression.
  • The Student record type holds the static list of all students.
  • Some of the constructor calls use named arguments to clarify which argument matches which constructor parameter.

Try adding a few more students with different test scores to the list of students to get more familiar with the code so far.

Create the query

Next, you create your first query. Your query, when you execute it, produces a list of all students whose score on the first test was greater than 90. Because the whole Student object is selected, the type of the query is IEnumerable<Student>. Although the code could also use implicit typing by using the var keyword, explicit typing is used to clearly illustrate results. (For more information about var, see Implicitly Typed Local Variables.) Add the following code to Program.cs, after the code that creates the sequence of students:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csDefineFirstQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

The query's range variable, student, serves as a reference to each Student in the source, providing member access for each object.

Run the query

Now write the foreach loop that causes the query to execute. Each element in the returned sequence is accessed through the iteration variable in the foreach loop. The type of this variable is Student, and the type of the query variable is compatible, IEnumerable<Student>. After you added the following code, build and run the application to see the results in the Console window.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csRunFirstQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

To further refine the query, you can combine multiple Boolean conditions in the where clause. The following code adds a condition so that the query returns those students whose first score was over 90 and whose last score was less than 80. The where clause should resemble the following code.

csharp
where student.Scores[0] > 90 && student.Scores[3] < 80  

Try the preceding where clause, or experiment yourself with other filter conditions. For more information, see where clause.

Order the query results

It's easier to scan the results if they are in some kind of order. You can order the returned sequence by any accessible field in the source elements. For example, the following orderby clause orders the results in alphabetical order from A to Z according to the family name of each student. Add the following orderby clause to your query, right after the where statement and before the select statement:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csOrderByLast

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

Now change the orderby clause so that it orders the results in reverse order according to the score on the first test, from the highest score to the lowest score.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csOrderByScore

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

Change the WriteLine format string so that you can see the scores:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csWriteFirstScore

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

For more information, see orderby clause.

Group the results

Grouping is a powerful capability in query expressions. A query with a group clause produces a sequence of groups, and each group itself contains a Key and a sequence that consists of all the members of that group. The following new query groups the students by using the first letter of their family name as the key.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csCreateGroupQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

The type of the query changed. It now produces a sequence of groups that have a char type as a key, and a sequence of Student objects. The code in the foreach execution loop also must change:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csRunGroupQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

Run the application and view the results in the Console window. For more information, see group clause.

Explicitly coding IEnumerables of IGroupings can quickly become tedious. Write the same query and foreach loop much more conveniently by using var. The var keyword doesn't change the types of your objects; it just instructs the compiler to infer the types. Change the type of studentQuery and the iteration variable group to var and rerun the query. In the inner foreach loop, the iteration variable is still typed as Student, and the query works as before. Change the student iteration variable to var and run the query again. You see that you get exactly the same results.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csVarGroupQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

For more information about var, see Implicitly Typed Local Variables.

Order the groups by their key value

The groups in the previous query aren't in alphabetical order. You can provide an orderby clause after the group clause. But to use an orderby clause, you first need an identifier that serves as a reference to the groups created by the group clause. You provide the identifier by using the into keyword, as follows:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csOrderedGroupQuery

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

Run this query, and the groups are now sorted in alphabetical order.

You can use the let keyword to introduce an identifier for any expression result in the query expression. This identifier can be a convenience, as in the following example. It can also enhance performance by storing the results of an expression so that it doesn't have to be calculated multiple times.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csQueryWithLet

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

For more information, see the article on the let clause.

Use method syntax in a query expression

As described in Query Syntax and Method Syntax in LINQ, some query operations can only be expressed by using method syntax. The following code calculates the total score for each Student in the source sequence, and then calls the Average() method on the results of that query to calculate the average score of the class.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csComputeAverage

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

To transform or project in the select clause

It's common for a query to produce a sequence whose elements differ from the elements in the source sequences. Delete or comment out your previous query and execution loop, and replace it with the following code. The query returns a sequence of strings (not Students), and this fact is reflected in the foreach loop.

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csSelectProjection

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}

Code earlier in this walkthrough indicated that the average class score is approximately 334. To produce a sequence of Students whose total score is greater than the class average, together with their Student ID, you can use an anonymous type in the select statement:

sample · csharpdocs/csharp/linq/get-started/snippets/WalkthroughWritingLinqQueries/Program.csBetterThanMost

csharp
// <CreateSequence>
using WalkthroughWritingLinqQueries;

// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
    new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
    new Student(First: "Claire",   Last: "O'Donnell",  ID: 112, Scores: [75, 84, 91, 39]),
    new Student(First: "Sven",     Last: "Mortensen",  ID: 113, Scores: [88, 94, 65, 91]),
    new Student(First: "Cesar",    Last: "Garcia",     ID: 114, Scores: [97, 89, 85, 82]),
    new Student(First: "Debra",    Last: "Garcia",     ID: 115, Scores: [35, 72, 91, 70]),
    new Student(First: "Fadi",     Last: "Fakhouri",   ID: 116, Scores: [99, 86, 90, 94]),
    new Student(First: "Hanying",  Last: "Feng",       ID: 117, Scores: [93, 92, 80, 87]),
    new Student(First: "Hugo",     Last: "Garcia",     ID: 118, Scores: [92, 90, 83, 78]),

    new Student("Lance",   "Tucker",      119, [68, 79, 88, 92]),
    new Student("Terry",   "Adams",       120, [99, 82, 81, 79]),
    new Student("Eugene",  "Zabokritski", 121, [96, 85, 91, 60]),
    new Student("Michael", "Tucker",      122, [94, 92, 91, 91])
];
// </CreateSequence>

// <DefineFirstQuery>
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
    from student in students
    where student.Scores[0] > 90
    select student;
// </DefineFirstQuery>

Console.WriteLine("\nRunning Query 1.............");
// <RunFirstQuery>
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
    Console.WriteLine($"{student.Last}, {student.First}");
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
//</RunFirstQuery>

Console.WriteLine("\nRunning OrderBy Query.............");
OrderByQuery();

Console.WriteLine("\nRunning Group Query.............");
GroupQuery();

Console.WriteLine("\nRunning Group Var Query.............");
GroupVarQuery();

Console.WriteLine("\nRunning Ordered Group Query.............");
OrderedGroupQuery();

Console.WriteLine("\nRunning Group Query With Let.............");
QueryWithLetVariable();

Console.WriteLine("\nRunning Compute Average.............");
ComputeAverage();

Console.WriteLine("\nRunning Select projection.............");
SelectProjection();

void OrderByQuery()
{
    // Create the query.
    // The first line could also be written as "var studentQuery ="
    IEnumerable<Student> studentQuery =
        from student in students
        where student.Scores[0] > 90
        // <OrderByLast>
        orderby student.Last ascending
        // </OrderByLast>
        // <OrderByScore>
        orderby student.Scores[0] descending
        // </OrderByScore>
        select student;

    Console.WriteLine("\nRunning Query 1.............");
    // Execute the query.
    // var could be used here also.
    foreach (Student student in studentQuery)
    {
        // <WriteFirstScore>
        Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
        // </WriteFirstScore>
    }
}

void GroupQuery()
{
    //<CreateGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];
    //</CreateGroupQuery>

    //<RunGroupQuery>
    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // Output:
    // O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    // M
    //   Mortensen, Sven
    // G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    // F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    // T
    //   Tucker, Lance
    //   Tucker, Michael
    // A
    //   Adams, Terry
    // Z
    //   Zabokritski, Eugene
    // </RunGroupQuery>
}

void GroupVarQuery()
{
    //<VarGroupQuery>
    IEnumerable<IGrouping<char, Student>> studentQuery =
        from student in students
        group student by student.Last[0];

    foreach (IGrouping<char, Student> studentGroup in studentQuery)
    {
        Console.WriteLine(studentGroup.Key);
        foreach (Student student in studentGroup)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }
    // </VarGroupQuery>
}

void OrderedGroupQuery()
{
    //<OrderedGroupQuery>
    var studentQuery4 =
        from student in students
        group student by student.Last[0] into studentGroup
        orderby studentGroup.Key
        select studentGroup;

    foreach (var groupOfStudents in studentQuery4)
    {
        Console.WriteLine(groupOfStudents.Key);
        foreach (var student in groupOfStudents)
        {
            Console.WriteLine($"   {student.Last}, {student.First}");
        }
    }

    // Output:
    //A
    //   Adams, Terry
    //F
    //   Fakhouri, Fadi
    //   Feng, Hanying
    //G
    //   Garcia, Cesar
    //   Garcia, Debra
    //   Garcia, Hugo
    //M
    //   Mortensen, Sven
    //O
    //   Omelchenko, Svetlana
    //   O'Donnell, Claire
    //T
    //   Tucker, Lance
    //   Tucker, Michael
    //Z
    //   Zabokritski, Eugene
    //</OrderedGroupQuery>
}

void QueryWithLetVariable()
{
    // <QueryWithLet>
    // This query returns those students whose
    // first test score was higher than their
    // average score.
    var studentQuery5 =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where totalScore / 4 < student.Scores[0]
        select $"{student.Last}, {student.First}";

    foreach (string s in studentQuery5)
    {
        Console.WriteLine(s);
    }

    // Output:
    // Omelchenko, Svetlana
    // O'Donnell, Claire
    // Mortensen, Sven
    // Garcia, Cesar
    // Fakhouri, Fadi
    // Feng, Hanying
    // Garcia, Hugo
    // Adams, Terry
    // Zabokritski, Eugene
    // Tucker, Michael
    // </QueryWithLet>
}

void ComputeAverage()
{
    // <ComputeAverage>
    var studentQuery =
        from student in students
        let totalScore = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        select totalScore;

    double averageScore = studentQuery.Average();
    Console.WriteLine($"Class average score = {averageScore}");

    // Output:
    // Class average score = 334.166666666667
    // </ComputeAverage>

    // <BetterThanMost>
    var aboveAverageQuery =
        from student in students
        let x = student.Scores[0] + student.Scores[1] +
            student.Scores[2] + student.Scores[3]
        where x > averageScore
        select new { id = student.ID, score = x };

    foreach (var item in aboveAverageQuery)
    {
        Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
    }

    // Output:
    // Student ID: 113, Score: 338
    // Student ID: 114, Score: 353
    // Student ID: 116, Score: 369
    // Student ID: 117, Score: 352
    // Student ID: 118, Score: 343
    // Student ID: 120, Score: 341
    // Student ID: 122, Score: 368
    // </BetterThanMost>
}

void SelectProjection()
{
    // <SelectProjection>
    IEnumerable<string> studentQuery =
        from student in students
        where student.Last == "Garcia"
        select student.First;

    Console.WriteLine("The Garcias in the class are:");
    foreach (string s in studentQuery)
    {
        Console.WriteLine(s);
    }

    // Output:
    // The Garcias in the class are:
    // Cesar
    // Debra
    // Hugo
    // </SelectProjection>
}