Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

LINQ Training

2,072 views

Published on

http://www.intertech.com/Courses/Course.aspx?CourseID=99333

This slide deck delivers an overview of Microsoft's .NET Language Integrated Query (LINQ)

Published in: Technology, Education
  • Be the first to comment

LINQ Training

  1. 1. Andrew Troelsen Intertech Principal Apress Author Copyright © Intertech, Inc. 2007. All Rights Reserved.
  2. 2. Objectives:  Understand the motivation behind LINQ.  Work with query operators and query expressions.  Apply LINQ expressions against containers of data.  Examine new .NET 3.5 C# / VB syntactical constructs.  Work with LINQ to ADO (LINQ to DataSet / LINQ to SQL). Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 2
  3. 3. Understanding the Role of LINQ  LINQ (Language Integrated Query) is a .NET 3.5 API which allows you to obtain data in a consistent manner. - LINQ query expressions are built from numerous query operators. - These query expressions are strongly typed. - Given this, we get compile time checking, IntelliSense, designer support and other bells and whistles. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 3
  4. 4.  LINQ query expressions can be applied to a variety of data sources. - LINQ can be used when interacting with relational databases (LINQ to ADO). - LINQ can be used when interacting with XML documents (LINQ to Xml). - As well, LINQ can be used to interact with any container implementing IEnumerable<T> (e.g., such as List<T>).  In a nutshell, LINQ provides a streamlined symmetry to the process of obtaining and manipulating ‘data’ in the broad sense of the term. - This is not to say that you will never use the ADO.NET / XML APIs. - However, using LINQ allows you to achieve the same results with less fuss and bother. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 4
  5. 5. LINQ Assemblies and Namespaces  The LINQ API is represented by three major assemblies, each of which has a number of namespaces / types. - System.Core.dll: This is the core LINQ assembly which defines types needed for any LINQ project. - System.Data.Linq.dll: Defines LINQ to SQL data types. This is required when using LINQ to access relational database. - System.Xml.Linq.dll: Defines LINQ to XML data types, required when using LINQ to manipulate XML documents. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 5
  6. 6. A First Look at LINQ  Before diving too deeply into the inner workings of LINQ, consider the following example. - Here we are using LINQ to iterate over items stored within an array of strings. - Although System.Array does not implement IEnumerable<T>, the necessary infrastructure is provided via extension methods. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 6
  7. 7. // C# static void QueryOverStrings() { // Assume we have an array of strings. string[] currentVideoGames = {quot;Morrowindquot;, quot;Dead Risingquot;, quot;Half Life 2: Episode 1quot;, quot;F.E.A.R.quot;, quot;Daxterquot;, quot;System Shock 2quot;}; // Build a query expression to represent the items in the array // which have more than 6 letters. IEnumerable<string> subset = from g in currentVideoGames where g.Length > 6 orderby g select g; // Print out the results (notice no Daxter!) foreach (string s in subset) Console.WriteLine(quot;Item: {0}quot;, s); } ' VB Sub QueryOverStrings() ' Assume we have an array of strings. Dim currentVideoGames = {quot;Morrowindquot;, quot;Dead Risingquot;, _ quot;Half Life 2: Episode 1quot;, quot;F.E.A.R.quot;, _ quot;Daxterquot;, quot;System Shock 2quot;} ' Build a query expression to represent the items in the array ' which have more than 6 letters. Dim subset As IEnumerable(Of String) = From g In currentVideoGames _ Where g.Length > 6 _ Select g _ Order By g ' Print out the results (notice no Daxter!) For Each s In subset Console.WriteLine(quot;Item: {0}quot;, s) Next End Sub Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 7
  8. 8.  Assume we pass in the ‘subset’ object into the following helper function. - Notice the object implementing IEnumerable<T> is a System.Query.OrderedSequence<T> type. - VB developers remove semi-colons ;-) static void ReflectOverQueryResults(object resultSet) { Console.WriteLine(quot;n***** Info about your query *****quot;); Console.WriteLine(quot;resultSet is of type: {0}quot;, resultSet.GetType().Name); Console.WriteLine(quot;resultSet location: {0}quot;, resultSet.GetType().Assembly); } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 8
  9. 9.  Other LINQ query expressions could return an entirely different type. - Consider the following LINQ query and output. - Notice ‘subset’ is of type WhereIterator. static void QueryOverInts() { int[] numbers = {10, 20, 30, 40, 1, 2, 3, 8}; // Only print items less than 10. var subset = from i in numbers where i < 10 select i; // VB Query would look like so: // Dim subset = From i In numbers _ // Where i < 10 _ // Select i // Print out the results. foreach (var i in subset) Console.Write(quot;Item: {0} quot;, i); ReflectOverQueryResults(subset); } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 9
  10. 10.  Because the underlying type returned from a LINQ query expression is seldom obvious, make use of the C# ‘var’ keyword: - VB developers simply omit the data type. - Recall this allows the compiler to determine the type of type. // C# var subset = from game in currentVideoGames where game.Length > 6 orderby game select game; ' VB Dim subset = From g In currentVideoGames _ Where g.Length > 6 _ Select g _ Order By g Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 10
  11. 11. LINQ Over Containers  Beyond iterating over simple fixed arrays, LINQ expressions can be applied to any type implementing IEnumerable<T>. - This includes a majority of the types within System.Collections.Generic. - It is possible to indirectly apply LINQ to non-generic containers as well. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 11
  12. 12.  Assume we have a generic List of Car types. - The Car type defines four points of data (PetName, Color, Speed and Make). - Under .NET 3.5, we can hydrate containers using object init syntax. Consider the following C# code. static void Main(string[] args) { // Make a List<> of Car objects // using the new init syntax. List<Car> myCars = new List<Car>() { new Car{ PetName = quot;Henryquot;, Color = quot;Silverquot;, Speed = 100, Make = quot;BMWquot;}, new Car{ PetName = quot;Daisyquot;, Color = quot;Tanquot;, Speed = 90, Make = quot;BMWquot;}, new Car{ PetName = quot;Maryquot;, Color = quot;Blackquot;, Speed = 55, Make = quot;VWquot;}, new Car{ PetName = quot;Clunkerquot;, Color = quot;Rustquot;, Speed = 5, Make = quot;Yugoquot;}, new Car{ PetName = quot;Melvinquot;, Color = quot;Whitequot;, Speed = 43, Make = quot;Fordquot;} }; } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 12
  13. 13.  We could now build an expression which returns only the Car objects which match our LINQ statement. - Here, we only want BMWs which are going over 55 MPH. // C# : Create a query expression. var fastCars = from c in myCars where c.Speed > 55 && c.Make == quot;BMWquot; select c; foreach (var car in fastCars) { Console.WriteLine(quot;{0} is going too fast!quot;, car.PetName); } ' VB : Create a query expression. Dim onlyFastBMWs = From c In cars _ Where c.Make = quot;BMWquot; And c.Speed >= 55 _ Select c For Each c In onlyFastBMWs Console.WriteLine(quot;{0} is going too fast!quot;, car.PetName) Next Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 13
  14. 14. Examining the Core LINQ Query Operators  C# and VB have a number of intrinsic LINQ query operators. - These operators are simply shorthand notations for using types (such as OrderedSequence) within the System.Linq namespace. - While you could build your query expressions using the types of System. Linq directly, doing so would be laborious. - Here is a partial list of LINQ operators. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 14
  15. 15. LINQ Query Meaning in Life Operator from / in These operators define the backbone for any LINQ expression. where Used to define a restriction for which items to extract from a container. select Used to select a sequence from the container. join / in / on / equals / into Performs joins based on specified key. Remember! These ‘joins’ do not need to have anything to do with data in a relational database. orderby / ascending / descending Allows the resulting subset to be ordered in ascending or descending orders. group / by / into These operators are used to yield a subset with data grouped by a specified value.  In its absolute simplest form, a LINQ query expression can be understood as so: - Notice the use of the from, in and select operators. // C# var result = from item in container select item; ' VB Dim result = From item In container _ Select item Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 15
  16. 16.  If you wish to obtain a result set based on a property or public field of the item, simply qualify your select clause. - If you wish to ensure you do not obtain duplicates, call Distinct() off the returned IEnumerable<T> compatible object. static void BasicSelection(Car[] myCars) { // Now get only the names of the cars. // VB: Dim names = From c In cars Select c.PetName var names = from c in myCars select c.PetName; foreach (var n in names) Console.WriteLine(quot;Name: {0}quot;, n); // Print out only distinct makes. var makes = from c in myCars select c.Make; foreach (var m in makes.Distinct<String>()) Console.WriteLine(quot;Make: {0}quot;, m); } ' VB Snippet Dim makes = From c In cars _ Select c.Make For Each m In makes.Distinct(Of String)() Console.WriteLine(quot;Make: {0}quot;, m) Next Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 16
  17. 17.  It is also possible to project new forms of data from an existing source. - To do so, simply make use of anonymous types. - Recall the compiler will automatically generate a type deriving from System.Object, with properties and backing fields for each name / value pair. // C#: Project a new set of makes & colors. var makesColors = from c in myCars select new {c.Make, c.Color}; foreach (var o in makesColors) { // Could also use Make and Color properties directly. Console.WriteLine(o.ToString()); } ' VB Dim makesColors = From c In cars _ Select New {c.Make, c.Color} For Each o In makesColors ' Could also use Make and Color properties directly. Console.WriteLine(o.ToString()) Next Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 17
  18. 18. • Ponder the following C# code sample, which extracts metadata descriptions for all public enumerations in mscorlib.dll. • The only major difference in the VB equivalent would be to use the And operator rather than the C# && operator. static void Main(string[] args) { // Get metadata descriptions for all types in mscorlib. Assembly corlib = Assembly.Load(quot;mscorlibquot;); Type[] typeInfo = corlib.GetTypes(); // Only get the public enums. // // VB: Dim enumTypes = From e in typeInfo Where _ // e.IsEnum = True And e.IsPublic Select e var enumTypes = from e in typeInfo where e.IsEnum == true && e.IsPublic select e; Console.WriteLine(quot;***** Here are all the public enums in mscorlib.dll *****nquot;); foreach (var e in enumTypes) Console.WriteLine(quot;Name: {0}quot;, e.ToString()); } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 18
  19. 19. • Here is yet another example, using a LINQ query to obtain information about files on the local hard drive. • Again, you could obviously perform the same task without LINQ, however by using LINQ, we have a more concise and symmetrical code base. static void Main() { Console.WriteLine(quot;C# files in MyCode folder and subdirectoriesnquot;); // First get all files in the MyCode folder and subdirectoris. DirectoryInfo dirInfo = new DirectoryInfo(@quot;C:MyCodequot;); FileInfo[] fileList = dirInfo.GetFiles(quot;*.*quot;, SearchOption.AllDirectories); // Create a LINQ query to get only C# files, ordered by file name. var fileQuery = from file in fileList where file.Extension == quot;.csquot; orderby file.Name select file; // Execute the query and show results. foreach (var fi in fileQuery) { Console.WriteLine(fi.FullName); } Console.ReadLine(); } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 19
  20. 20. • Under the hood of LINQ query operators. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 20
  21. 21. LINQ Over Relational Databases  LINQ to ADO.NET is the term used to define two aspects of the LINQ programming model: - LINQ to DataSet: Applying LINQ queries to ADO.NET DataSet objects (specifically, the DataTable objects within a DataSet). - LINQ to SQL: Applying LINQ queries to interact with relational databases. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 21
  22. 22.  LINQ to Dataset provides yet another way to iterate over the data of an ADO.NET Dataset. - By default, you cannot directly apply a LINQ query to a Dataset. - Rather, you must obtain an ‘enumerable’ version of the data. - At this point, you can apply any flavor of LINQ queries.  System.Data.DataSetExtensions.dll is the assembly which provides this support. - The DataTableExtensions class defines extension methods for the DataTable type. - The DataRowExtensions type defines other extensions for DataRow. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 22
  23. 23. // C# private static void ApplyLinqQuery(DataTable data) { // Project a new result set containing // the ID / color for rows with a CarID > 5 var cars = from car in data.AsEnumerable() where (int)car[quot;CarIDquot;] > 5 select new { ID = (int)car[quot;CarIDquot;], Color = (string)car[quot;Colorquot;] }; Console.WriteLine(quot;Cars with ID greater than 5:quot;); foreach (var item in cars) { Console.WriteLine(quot;-> CarID = {0} is {1}quot;, item.ID, item.Color); } } ' VB Sub ApplyLinqQuery(ByVal data As DataTable) ' Project a new result set containing ' the ID / color for rows with a CarID > 5 Dim cars = From car In data.AsEnumerable() _ Where CInt(car(quot;CarIDquot;) > 5) _ Select New With _ { _ .ID = CInt(car(quot;CarIDquot;)), _ .Color = CStr(car(quot;Colorquot;)) _ } Console.WriteLine(quot;Cars with ID greater than 5:quot;) For Each item In cars Console.WriteLine(quot;-> CarID = {0} is {1}quot;, item.ID, item.Color) Next End Sub Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 23
  24. 24. • Consider the following update to the LINQ query. • Using the generic Field() extension method, we obtain better type safety. // C# var cars = from car in data.AsEnumerable() where car.Field<int>(quot;CarIDquot;) > 5 select new { ID = car.Field<int>(quot;CarIDquot;), Color = car.Field<string>(quot;Colorquot;) }; ' VB Dim cars = From car In data.AsEnumerable() _ Where car.Field(Of Integer)(quot;CarIDquot;) > 5 _ Select New With _ { _ .ID = car.Field(Of Integer)(quot;CarIDquot;), _ .Color = car.Field(Of String)(quot;Colorquot;) _ } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 24
  25. 25.  When applying LINQ to databases, you must first define an ‘entity class’. - Entity classes are similar to strongly typed datasets; they provide strong typing for fields on the remote database table. - Entity classes can be created manually, using the sqlmetal.exe command line tool or via Visual Studio. - In all cases, various LINQ-centric attributes are used to qualify the functionality of the entity class’s members.  Once you have defined your entity classes, you can make use of the DataContext type to execute your queries. - DataContext provides support for inserting, deleting, selecting, updating data. - You can also call stored procedures (among other details). Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 25
  26. 26.  Assume a database named AutoLot which has a single table named Inventory. - The inventory contains fields which represent the automobiles on hand (make, color, pet name, ID). - We could model this table with the following entity class. - The attributes shown are members of the System.Data.Linq namespace. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 26
  27. 27. // C# code. VB developers apply VB attribute syntax (e.g., <Table>) [Table] public class Inventory { [Column] public string Make; [Column] public string Color; [Column] public string PetName; // Identify the primary key. [Column(IsPrimaryKey = true)] public int CarID; // Note that entity classes can have ‘normal’ members // which do not map to the database table. public override string ToString() { return string.Format(quot;ID = {0}; Make = {1}; Color = {2}; PetName = {3}quot;, CarID, Make.Trim(), Color.Trim(), PetName.Trim()); } } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 27
  28. 28.  Now consider the following direct usage of the DataContext type. - Most often, DataContext is subclasses to allow for strong typing. - Notice the generic DataContext.GetTable() method requires an entity class instance. - After this point, simply apply a LINQ query against the context. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 28
  29. 29. class Program { const string cnStr = quot;Data Source=localhost;Initial Catalog=AutoLot;uid='sa';pwd=quot;; static void Main(string[] args) { Console.WriteLine(quot;***** DLinq Sample App *****nquot;); // Create a DataContext object. DataContext db = new DataContext(cnStr); // Now create a Table<> type. // VB: Dim invTable As Table(Of Inventory) = db.GetTable(Of Inventory)() Table<Inventory> invTable = db.GetTable<Inventory>(); // Show all data using a LINQ query. Console.WriteLine(quot;-> Contents of Inventory Table from Cars database:nquot;); foreach (var car in from c in invTable select c) Console.WriteLine(car.ToString()); } } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 29
  30. 30.  Here is a strongly typed entity class, and the updated Main() method. - Notice that the internal Table<T> type is created at runtime, so we do not need to allocate this member variable. ' VB Class CarsDatabase class CarsDatabase : DataContext Inherits DataContext { Public Inventory As Table(Of Inventory) // This is created at runtime. public Table<Inventory> Inventory; Public Sub New(ByVal connectionString As String) MyBase.New(connectionString) public CarsDatabase(string connectionString) End Sub : base(connectionString){} End Class } static void Main(string[] args) { Console.WriteLine(quot;***** DLinq Sample App *****nquot;); // Create a CarsDatabase object. CarsDatabase db = new CarsDatabase(cnStr); // Show all data. Console.WriteLine(quot;-> Contents of Inventory Table from Cars database:nquot;); foreach (var car in from c in db.Inventory select c) Console.WriteLine(car.ToString()); Console.ReadLine(); } Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 30
  31. 31. Automating the Creation of Entity Classes  Building entity classes by hand for complex databases would be very painful. - The LINQ CTP ships with a command line tool named sqlmetal.exe, located under C:Program FilesLINQ PreviewBin. - This tool will create entity classes on your behalf via various command line arguments. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 31
  32. 32.  Visual Studio also provides several new project items which can be used to generate entity classes. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 32
  33. 33. • Demo! • Visual Studio 2008 LINQ to SQL Designer Support Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 33
  34. 34. • LINQ is a programming model which allows you to apply strongly typed queries to a variety of containers. • LINQ query statements are shorthand notations for working with a full-blown object model. • LINQ to ADO is an API which allows you to apply LINQ queries to DataSet objects & relational databases. Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 34
  35. 35. ? Copyright © Intertech, Inc. 2007 • www.Intertech.com • 800-866-9884 • Slide 35

×