12. LINQ to Objects

About this Tutorial

Objectives

Delegates will learn to develop applications using C# 4.5. After completing this course, delegates will be able to:

  • Use Visual Studio 2012 effectively
  • Create commercial C# Web Applications
  • Develop multi-threaded applications, Use WCF and LINQ

Audience

This course has been designed primarily for programmers new to the .Net development platform. Delegates experience solely in Windows application development or earlier versions of C# will also find the content beneficial.

Prerequisites

No previous experience in C# programming is required. But any experience you do have in programming will help. Also no experience in Visual Studio is required. But again any experience you do have with programming development environments will be a valuable.

Download Solutions

HTML tutorial


Overview

  1. LINQ = “Language Integrated Query”
  2. Or to put it another way:
    • A set of C# (VB etc) keywords and .NET types, methods, etc.
    • …to query data from various data sources.
  3. The Purpose of LINQ:
    • LINQ provides a unified syntax for querying data:
      • Regardless of where the data is coming from.
    • Better than the pre-LINQ situation, where you have to use completely different query syntaxes:
      • Objects in memory – Use arrays and/or .NET collection classes APIs.
      • Relational data – Use ADO.NET connections, ADO.NET DataSets, etc…
      • XML – Use DOM, XmlReader, XmlWriter, etc.
  4. LINQ Variations:
    • There are several LINQ variations currently available:
      • LINQ to objects.
      • LINQ to XML.
      • LINQ to DataSet.
      • LINQ to SQL.
      • LINQ to Entities.
    • Plus many 3rd-party LINQ providers, such as:
      • LINQ to Excel.
      • LINQ to Google.
      • LINQ to SharePoint.
  5. A Few Technical Details:
    • LINQ queries use SQL-like syntax:
      • Via C# keywords such as select, from, where, etc…
      • Can manipulate data sources that implements IEnumerable<T>.
      • LINQ queries are strongly typed.
    • C# / .NET features utilized by LINQ:
      • Implicitly-typed local variables.
      • Extension methods.
      • Object/collection initialization syntax.
      • Anonymous types.
      • Lambda expressions.

Estimated Time – 1 Hour

Not what you are looking? Try the next tutorial – ADO.NET Entity Framework

Lab 1: Using LINQ with Arrays

Lab 1: Using LINQ with Arrays

Overview

  1. In this section, we’ll show how to use LINQ to query data in an array:
    • See the LinqOverArrays project
    • Automatically references LINQ-related assemblies
      startLinq
  2. C# LINQ Query Operators:
    LinqOps
  3. Here’s a traditional array-processing example – Uses manual iteration / conditional logic and doesn’t use LINQ –
    private static void DemoNonLinq()
    {
     // Here's an array of strings.
     string[] cities = { "Boston", "New York", "Dallas", "St. Paul", "Las Vegas" };
     // Get the cities that contain a space character.
     string[] citiesWithSpaces = new string[cities.Length];
     for (int i = 0; i < cities.Length; i++)
      ...
     Console.WriteLine("Cities with spaces (without using LINQ): ");
     ...
    }
  4. View code file.
  5. Here is the same functionality but using LINQ to do so:
    • Builds a LINQ query expression using query operators.
    • Query is executed when we enumerate it in the loop.
    • Assigns to var query variable (IEnumerable actually).

    private static void DemoLinq()
    {
     // Here's an array of strings.
     string[] cities = { "Boston", "New York", "Dallas", "St. Paul", "Las Vegas" };
     // Use a LINQ query expression to get the cities that contain a space character.
     var subset = from c in cities
            where c.Contains(" ")
            orderby c.Length
            ascending
            select c;
     Console.WriteLine("\nCities with spaces (using LINQ): ");
     foreach (var s in subset)
       Console.WriteLine("City: {0}", s);
    }

  6. View code file.
  7. Deferred Execution:
    • LINQ queries use a “deferred execution” model.
    • Executed when you enumerate the query, not when you create it.
    • Therefore, if you enumerate a query several times, the query will be executed afresh each time.
      private static void DemoDeferredExecution()
      {
       int[] examMarks = { 62, 75, 85, 59, 96, 80 };
       // Get the "A" grades, i.e. >= 70.
       var subset = from m in examMarks where m >= 70 select m;
       Console.WriteLine("\nA-grade exams (LINQ query is executed here):");
       ...
    • View code file.
  8. Immediate Execution:
    • If you want to execute a query immediately:
      • Invoke the ToArray() extension method – Executes the query and places the result in a T[] array.
      • Or invoke the ToList() extension method – Executes the query and places the result in a List.
    • Example code –
      private static void DemoImmediateExecution()
      {
       int[] examMarks = { 62, 75, 85, 59, 96, 80 };
       // Execute query immediately, and get result as int[].
       int[] arrayOfGradeAs =
              (from m in examMarks where m >= 70 select m).ToArray();
       // Get data RIGHT NOW as List.
       List listOfGradeAs =
              (from m in examMarks where m >= 70 select m).ToList();
      }
    • View code file.
  9. Returning Queries vs. Returning Results:
    • This method returns a query – Client will execute the query to obtain result (presumably).
      private static IEnumerable DemoReturningQuery()
      {
       int[] examMarks = { 62, 75, 85, 59, 96, 80 };
       IEnumerable query = from m in examMarks where m >= 70 select m;
       return query;
      }
    • View code file.
    • This method executes the query and returns the result – No need for client to execute query, it’s already done –
      private static int[] DemoReturningResult()
      {
       int[] examMarks = { 62, 75, 85, 59, 96, 80 };
       IEnumerable query = from m in examMarks where m >= 70 select m;
       return query.ToArray();
      }
    • View code file.

Lab 2: Using LINQ with Collections

Lab 2: Using LINQ with Collections
  1. A quick bit of info on LINQ and Collections before we crack on with a lab.
    • You can use generic collections in LINQ queries – Generic collections implement IEnumerable.
    • You can’t use raw collections in LINQ queries – Raw collections don’t implement IEnumerable, you must convert into an IEnumerable collection e.g. –
      // Raw ArrayList of Product objects.
      ArrayList products = new ArrayList()
      {
       new Product { Description = "3D HD-TV",    Price = 1500, InStock = 3 },
       new Product { Description = "BlueRay Player", Price = 200, InStock = 10 },
       ...
      };
      // Transform ArrayList into an IEnumerable collection.
      var enumerable = products.OfType();
    • View code file.
    • You can filter data in a collection, to retrieve only those objects of a specific type – Use the OfType() extension method
      e.g. –
      // Raw ArrayList of various object types.
      ArrayList myStuff = new ArrayList()
      {
       3, 12, 1964, true, new Product(), "super swans"
      };
      // Transform ArrayList into an IEnumerable, ignores the non-ints.
      IEnumerable myInts = myStuff.OfType();
    • View code file.
  2. LINQ

Lab
  1. Now for our lab – we are going to create lottery number application and do a few things with the numbers.
  2. Open up Visual Studio, New Project C#>Windows>Console Application and call this LotteryNumbers
    AppForm1
  3. We wont be creating any separate classes so all the methods will go into the program.cs class.
  4. Into the Main() method add this code that creates our lottery numbers and then calls the relevant methods that we are going to create –
    int[] lotteryNumbers = { 13, 45, 28, 57, 92, 31 };
     OutputAllNumbers(lotteryNumbers);
     OutputNumbersInOrder(lotteryNumbers);
     OutputSquares(lotteryNumbers);
     OutputOddNumbers(lotteryNumbers);
     OutputSumAvgMinMax(lotteryNumbers);
    Console.ReadLine();
  5. View code file.
  6. The first method is the output all numbers method which gets all the numbers of the type int from the array and prints them –
    private static void OutputAllNumbers(int[] nums)
    {
     var query = (from i in nums select i);
     Console.WriteLine("All numbers:");
     foreach (var i in query)
     {
      Console.WriteLine(i);
     }
    }
  7. View code file.
  8. The next method will print each of the numbers in a list in either ascending or descending order using the key word order in the LINQ –
    private static void OutputNumbersInOrder(int[] nums)
    {
     var ascQuery = (from i in nums orderby i select i);
     var descQuery = (from i in nums orderby i descending select i);
     Console.WriteLine("\nNumbers in ascending order:");
     foreach (var i in ascQuery)
     ...
     Console.WriteLine("\nNumbers in descending order:");
     foreach (var i in descQuery)
     ...
    }
  9. View code file.
  10. The next method will square each of the numbers in the array sent to it using LINQ by using select i*i –
    private static void OutputSquares(int[] nums)
    {
     var sqQuery = (from i in nums select i * i);
     Console.WriteLine("\nSquares:");
     foreach (var i in sqQuery)
     {
      Console.WriteLine(i);
     }
    }
  11. View code file.
  12. The next method will print all the odd numbers by using a neat little trick where if the number cant be divided 2 then it will hence have a remainder(!=0) and so you can just print these numbers –
    private static void OutputOddNumbers(int[] nums)
    {
     var oddQuery = (from i in nums where i % 2 != 0 select i);
     Console.WriteLine("\nOdd numbers:");
     foreach (var i in oddQuery)
     {
      Console.WriteLine(i);
     }
    }
  13. View code file.
  14. Now the last method uses some of the extension methods that comes with using arrays and integers to allow you to simply call another method to return a result and hence print the average, min etc… –
    private static void OutputSumAvgMinMax(int[] nums)
    {
     var sumQuery = (from i in nums select i).Sum();
     var avgQuery = (from i in nums select i).Average();
     var minQuery = (from i in nums select i).Min();
     var maxQuery = (from i in nums select i).Max();
      Console.WriteLine("\nSum: {0}", sumQuery);
      Console.WriteLine("Avg: {0}", avgQuery);
      Console.WriteLine("Min: {0}", minQuery);
      Console.WriteLine("Max: {0}", maxQuery);
    }
  15. View code file.
  16. Now running the application
    app1

Lab 3: LINQ techniques

Lab 3: LINQ techniques
  1. A little bit of new ways of selecting objects and then we will start with the lab which carries on with a bank system made in an earlier tutorial
  2. Selecting full queries – This example recaps how to query full objects
    private static void DemoFullObjectQueries(Product[] products)
    {
     Console.WriteLine("Low-stock product details:");
     var prods = from p in products
           where p.InStock < 5
           select p;
     foreach (var p in prods)
      Console.WriteLine("\t{0}", p);
    }
  3. View code file.
  4. Selecting specific fields – Specify the required field in the select clause
    private static void DemoSpecificFieldQueries(Product[] products)
    {
     Console.WriteLine("\nLow-stock product prices:");
     var prices = from p in products
            where p.InStock < 5
            select p.Price;
     foreach (var p in prices)
      Console.WriteLine("\t{0:c}", p);
    }
  5. View code file.
  6. Selecting transformed data – Specify the required transformation in the select clause
    private static void DemoTransformedDataQueries(Product[] products)
    {
      Console.WriteLine("\nProducts summaries:");
      var summaries = from p in products
              select String.Format("{0}: {1} stock level",
                         p.Description,
                         p.InStock < 5 ? "low" : "normal");
      foreach (var summary in summaries)
        Console.WriteLine("\t{0}", summary);
    }
  7. View code file.
  8. Selecting projections – A projection is an anonymous type, contains the properties specified in the select clause
    private static void DemoProjectionQueries(Product[] products)
    {
     Console.WriteLine("\nLow-stock products and prices:");
     var projs = from p in products
           where p.InStock < 5
           select new { p.Description, p.Price };
     foreach (var p in projs)
      Console.WriteLine("\t{0}, {1:c}", p.Description, p.Price);
    }
  9. View code file.
Lab
  1. Now for our bank system application that we are going to create; it is going to use a previous application to build off this is called BankSystemInitial which can be downloaded from the top of the page.
  2. Start by opening the application, there is 3 classes there but we are going to only be using program.cs with the LINQ and then using the functionality provided by the other classes.
  3. Lets write our three methods first that you can see, one to show all account details, one to output name and balance for an account and then the last to show the transactions.
  4. we will start with showing the full details by getting all accounts
    private static void OutputFullDetailsForAllAccounts(List accounts)
    {
     Console.WriteLine("\nFull details for all accounts:");
     var query = (from a in accounts select a);
     foreach (var a in query)
     {
      Console.WriteLine("Account holder: {0}, balance: {1}, num transactions: {2}", a.AccountHolder, a.Balance, a.Transactions.Count);
     }
    }
  5. View code file.
  6. The next method shows the accounts names and balance for each account using LINQ –
    private static void OutputNameAndBalanceForAllAccounts(List accounts)
    {
     Console.WriteLine("\nName and balance for all accounts:");
     var query = from a in accounts
     select new { a.AccountHolder, a.Balance };
     foreach (var item in query)
     {
      Console.WriteLine("Account holder: {0}, balance: {1}", item.AccountHolder, item.Balance);
     }
    }
  7. View code file.
  8. The last method will show any accounts that have a balance that is greater or equal to 0 and transactions that are less then 10
    private static void OutputInCreditFewTransactionsAccounts(List accounts)
    {
     Console.WriteLine("\nAccounts in credit, with = 0 && a.Transactions.Count < 10
     select a;
     foreach (var a in query)
     {
      Console.WriteLine("Account holder: {0}, balance: {1}, num transactions: {2}", a.AccountHolder, a.Balance, a.Transactions.Count);
     }
     Console.WriteLine();
    }
  9. View code file.
  10. Now lets add some code to Main() to show you how this works. So lets add some new dummy accounts –
    // Create a collection using collection initializer syntax.
    List accounts<BankAccount> = new List<BankAccount>
    {
     new BankAccount { AccountHolder = "Huey", Balance = 4000 },
     new BankAccount { AccountHolder = "Lewey", Balance = 5000 },
     new BankAccount { AccountHolder = "Dewey" } ,
     new BankAccount { AccountHolder = "Donald", Balance = 10000 }
    };
  11. View code file.
  12. Now lets do some transactions and then we can use our new methods that we have created to show you the results
    // Do some transactions.
    for (int i = 0; i < 5; i++)
    {
     accounts[0].Deposit(i * 100);
    }
    for (int i = 0; i < 20; i++)
    {
     accounts[1].Deposit(i * 100);
    }
    accounts[2].Withdraw(10000);
     OutputFullDetailsForAllAccounts(accounts);
     OutputNameAndBalanceForAllAccounts(accounts);
     OutputInCreditFewTransactionsAccounts(accounts);
    Console.ReadLine();
  13. View code file.
  14. Hopefully the result of which will look something like this –
    app2

 

Well done. You have completed the tutorial in the C# course. The next tutorial is

13. ADO.NET Entity Framework


Back to beginning
Copyright © 2016 TalkIT®






If you liked this post, please comment with your suggestions to help others.
If you would like to see more content like this in the future, please fill-in our quick survey.
Scroll to Top