Top Banner
chlink Infoware Pvt. Ltd. Page 1 of 33 5 Dec 2010 LINQ Training Visual Basic LINQ Language-Integrated Query
33
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Linq

Techlink Infoware Pvt. Ltd. Page 1 of 335 Dec 2010

LINQ Training Visual Basic

LINQ

Language-Integrated Query

Page 2: Linq

Techlink Infoware Pvt. Ltd. Page 2 of 335 Dec 2010

LINQ Training Visual Basic

Table of content What is LINQ Language Features that Enable LINQ Flavors of LINQ LINQ Architecture LINQ to Objects

Query expressionsImplicitly Typed Variables Object initializerAnonymous typesExtension MethodsLambda expressionsMore on Queries

Page 3: Linq

Techlink Infoware Pvt. Ltd. Page 3 of 335 Dec 2010

LINQ Training Visual Basic

Table of content LINQ to Dataset

Single-Table Queries (LINQ to DataSet) Cross-Table Queries (LINQ to DataSet) Accessing Values without using Field methodAccessing Values using Field methodAdvantage of using Field method and SetField

methodQuerying Typed DataSets

Page 4: Linq

Techlink Infoware Pvt. Ltd. Page 4 of 335 Dec 2010

LINQ Training Visual Basic

What is LINQ

LINQ (often overheard pronounced as "link") is a step in the evolution of data access. It is a programming model that brings a much needed uniformity to accessing data from files, XML, database, registry, event log, and a whole host of other sources of data such as Active Directory and even services from 3rd parties such as Flickr.

It is designed to work with all shapes and sizes of different data and allow you to perform Query, Set, and Transform operations on all of it. Pretty much anything that implements IEnumerable is a target for LINQ.

Page 5: Linq

Techlink Infoware Pvt. Ltd. Page 5 of 335 Dec 2010

LINQ Training Visual Basic

Language Features that Enable LINQ

LINQ makes heavy use of Generics. Additionally, there were a number of features added to the Visual Basic and C# languages specifically to support LINQ. A couple of my more recent articles introduced some of these language features as a precursor to LINQ. The following contains a partial list of the language features that help enable LINQ and a brief description of each:

Type inference: Shorthand indicating the variables type is the compile time type of the right hand assignment

Extension Methods: Extending an existing value or reference type without deriving a new type

Object initializer: Short form of object initialization syntax that generates the equivalent code

Anonymous types: Create statements without constructing a method or type

Lambda expressions: Concise way of creating inline methods

Query expressions: SQL-like statements within code for manipulating objects

Page 6: Linq

Techlink Infoware Pvt. Ltd. Page 6 of 335 Dec 2010

LINQ Training Visual Basic

Flavors of LINQ

There are a variety of flavors of LINQ for accessing and manipulating different data sources. The trailing list contains some of the data domains provided by Microsoft. Some of these will be topics of future .NET Nuts and Bolts articles.

LINQ to Objects: Manipulates collections of objects

LINQ to DataSets: Manipulates a DataSet using LINQ

LINQ to SQL: Maps between custom types and a physical database table schema

LINQ to Entities: Uses a conceptual Entity Data Model to create a conceptual model of a physical database

LINQ to XML: Allows querying and manipulation of XML

Page 7: Linq

Techlink Infoware Pvt. Ltd. Page 7 of 335 Dec 2010

LINQ Training Visual Basic

LINQ Architecture

Page 8: Linq

Techlink Infoware Pvt. Ltd. Page 8 of 335 Dec 2010

LINQ Training Visual Basic

LINQ to Objects

Page 9: Linq

Techlink Infoware Pvt. Ltd. Page 9 of 335 Dec 2010

LINQ Training Visual Basic

LINQ to ObjectsThe term "LINQ to Objects" refers to the use of LINQ queries with any IEnumerable orIEnumerable(Of T) collection directly, without the use of an intermediate LINQ provider or API suchas LINQ to SQL or LINQ to XML. You can use LINQ to query any enumerable collections such asList(Of T), Array, or Dictionary(Of TKey, TValue). The collection may be user-defined or may bereturned by a .NET Framework API.

In a basic sense, LINQ to Objects represents a new approach to collections. In the old way, you hadto write complex foreach loops that specified how to retrieve data from a collection. In the LINQapproach, you write declarative code that describes what you want to retrieve.

In addition, LINQ queries offer three main advantages over traditional foreach loops:

1. They are more concise and readable, especially when filtering multiple conditions.2. They provide powerful filtering, ordering, and grouping capabilities with a minimum of application

code.3. They can be ported to other data sources with little or no modification.

Page 10: Linq

Techlink Infoware Pvt. Ltd. Page 10 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQQuery Expressions

Query expressions in Visual Basic 2008 can be expressed in a declarative syntax similar to that of SQL or XQuery. At compile time, query syntax is converted into method calls to a LINQ provider's implementation of the standard query operator extension methods. Applications control which standard query operators are in scope by specifying the appropriate namespace with an Imports statement. Syntax for a Visual Basic query expression looks like this:

Dim londonCusts = From cust In customers _ Where cust.City = "London" _ Order By cust.Name Ascending _ Select cust.Name, cust.Phone

Page 11: Linq

Techlink Infoware Pvt. Ltd. Page 11 of 335 Dec 2010

LINQ Training Visual Basic

LINQ Query SyntaxDestination var <variable> = Using type inference to assign the

resulting value(s)

Source from <item> in <data source> Information source providing a set of item (s)

Filter where <expression>, distinct Expression specifying the selection Criteria

Order order by <expression>, <expression> [Ascending | Descending]

Control the ordering of the results

Aggregate count([<expression>]), sum(<expression>), min(<expression>), max

(<expression>), avg(<expression>)

Aggregate the source items

Projection select <expression> Shaping the output

Page 12: Linq

Techlink Infoware Pvt. Ltd. Page 12 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQImplicitly Typed Variables

Instead of explicitly specifying a type when you declare and initialize a variable, you can now enable the compiler to infer and assign the type, as shown in the following example. This is referred to as local type inference.

' The variable number will be typed as an integer.

Dim aNumber = 5

' The variable name will be typed as a String. Dim aName = "Virginia"

Page 13: Linq

Techlink Infoware Pvt. Ltd. Page 13 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQObject Initializers

Object initializers are used in query expressions when you have to create an anonymous type to hold the results of a query. They also can be used to initialize objects of named types outside of queries. By using an object initializer, you can initialize an object in a single line without explicitly calling a constructor. Assuming that you have a class named Customer that has public Name and Phone properties, along with other properties, an object initializer can be used in this manner:

Dim aCust As Customer = New Customer With {.Name = "Mike", _ .Phone = "555-0212"}

Page 14: Linq

Techlink Infoware Pvt. Ltd. Page 14 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQAnonymous Types

Anonymous types provide a convenient way to temporarily group a set of properties into an element that you want to include in a query result. This enables you to choose any combination of available fields in the query, in any order, without defining a named data type for the element. An anonymous type is constructed dynamically by the compiler. The name of the type is assigned by the compiler, and it might change with each new compilation. Therefore, the name cannot be used directly. Anonymous types are initialized in the following way:

' Outside a query. Dim product = New With {.Name = "paperclips", .Price = 1.29} ' Inside a query. ' You can use the existing member names of the selected fields, as was ' shown previously in the Query Expressions section of this topic. Dim londonCusts1 = From cust In customers_

Where cust.City = "London“ _ Select cust.Name, cust.Phone

' Or you can specify new names for the selected fields. Dim londonCusts2 = From cust In customers _

Where cust.City = "London" _ Select CustomerName = cust.Name, _ CustomerPhone = cust.Phone

Page 15: Linq

Techlink Infoware Pvt. Ltd. Page 15 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQExtension Methods

Extension methods enable you to add methods to a data type or interface from outside the definition. This feature enables you to, in effect, add new methods to an existing type without actually modifying the type. The standard query operators are themselves a set of extension methods that provide LINQ query functionality for any type that implements IEnumerable(Of T). Other extensions to IEnumerable(Of T) include Count, Union, and Intersect.

' Import System.Runtime.CompilerServices to use the Extension attribute. <Extension()> _ Public Sub Print(ByVal str As String)

Console.WriteLine(str) End Sub

Dim greeting As String = "Hello" greeting.Print()

The following extension method adds a print method to the String class.

The method is called like an ordinary instance method of String:

Page 16: Linq

Techlink Infoware Pvt. Ltd. Page 16 of 335 Dec 2010

LINQ Training Visual Basic

Language Features That Support LINQLambda Expressions

A lambda expression is a function without a name that calculates and returns a single value. Unlike named functions, a lambda expression can be defined and executed at the same time. The following example displays 4.

Console.WriteLine((Function(num As Integer) num + 1)(3))

You can assign the lambda expression definition to a variable name and then use the name to call the function. The following example also displays 4.

Dim add1 = Function(num As Integer) num + 1 Console.WriteLine(add1(3))

In LINQ, lambda expressions underlie many of the standard query operators. The compiler creates lambda expressions to capture the calculations that are defined in fundamental query methods such as Where, Select, Order By, Take While, and others.For example, the following code defines a query that returns all senior students from a list of students.

Dim seniorsQuery = From stdnt In students Where stdnt.Year = "Senior" Select stdnt

The query definition is compiled into code that is similar to the following example, which uses two lambda expressions to specify the arguments for Where and Select.

Dim seniorsQuery2 = students Where(Function(st) st.Year = "Senior") Select(Function(s) s)

Page 17: Linq

Techlink Infoware Pvt. Ltd. Page 17 of 335 Dec 2010

LINQ Training Visual Basic

More On QueriesLike normal SQL queries we can do the following operations by using LINQ expressions

Clause Name Descriptions

Aggregate Clause Describes the Aggregate clause, which applies one or more aggregate functions to a collection

Distinct Clause Describes the Distinct clause, which restricts the values of the current range variable to eliminate duplicate values in query results.

From Clause Describes the From clause, which specifies a collection and a range variable for a query.

Group By Clause Describes the Group By clause, which groups the elements of a query result and can be used to apply aggregate functions to each group.

Group Join Clause Describes the Group Join clause, which combines two collections into a single hierarchical collection.

Join Clause Describes the Join clause, which combines two collections into a single collection.

Let Clause Describes the Let clause, which computes a value and assigns it to a new variable in the query.

Order By Clause Describes the Order By clause, which specifies the sort order for columns in a query.

Select Clause Describes the Select clause, which declares a set of range variables for a query

Skip Clause Describes the Skip clause, which bypasses a specified number of elements in a collection and then returns the remaining elements.

Page 18: Linq

Techlink Infoware Pvt. Ltd. Page 18 of 335 Dec 2010

LINQ Training Visual Basic

More On QueriesLike normal SQL queries we can do the following operations by using LINQ expressions

Clause Name Descriptions

Take Describes the Take clause, which returns a specified number of contiguous elements from the start of a

Collection

Take While Describes the Take While clause, which includes elements in a collection as long as a specified condition is true and bypasses the remaining elements.

Where Clause Describes the Where clause, which specifies a filtering condition for a query.

Skip While Clause Describes the Skip While clause, which bypasses elements in a collection as long as a specified condition is true and then returns the remaining elements.

Page 19: Linq

Techlink Infoware Pvt. Ltd. Page 19 of 335 Dec 2010

LINQ Training Visual Basic

Queries – Order By Clause Specifies the sort order for a query result.

Syntax:

Order By orderExp1 [ Ascending | Descending ] [, orderExp2 [...] ]

Example

The following query expression uses a From clause to declare a range variable book for the books collection.

The Order By clause sorts the query result by price in ascending order (the default). Books with the same price are sorted by title in ascending order. The Select clause selects only the Title property as the value returned by the query.

Dim titlesAscendingPrice = From book In books Order By book.Price, book.Title Select book.Title, book.Price

The following query expression uses the Order By clause to sort the query result by price in descending order. Books with the same price are sorted by title in ascending order.

Dim titlesDescendingPrice = From book In books Order By book.Price Descending, book.Title _ Select book.Title, book.Price

Dim bookOrders = From book In books Select book.Title, book.Price, book.PublishDate, book.Author _ Order By Author, Title, Price

Page 20: Linq

Techlink Infoware Pvt. Ltd. Page 20 of 335 Dec 2010

LINQ Training Visual Basic

Queries – Distinct By Clause Restricts the values of the current range variable to eliminate duplicate values in subsequent query clauses.

You can use the Distinct clause to return a list of unique items. The Distinct clause causes the query to ignore duplicate query results. The Distinct clause applies to duplicate values for all return fields specified by the Select clause. If no Select clause is specified, the Distinct clause is applied to the range variable for the query identified in the From clause. If the range variable is not an immutable type, the query will only ignore a query result if all members of the type match an existing query result.

Example

The following query expression joins a list of customers and a list of customer orders. The Distinct clause is included to return a list of unique customer names and order dates.

Dim customerOrders = From cust In customers, ord In orders _ Where cust.CustomerID = ord.CustomerID _Select cust.CompanyName, ord.OrderDate Distinct

Page 21: Linq

Techlink Infoware Pvt. Ltd. Page 21 of 335 Dec 2010

LINQ Training Visual Basic

Queries – From Clause Specifies one or more range variables and a collection to query.

Syntax:

From element [ As type ] In collection [ _ ][, element2 [ As type2 ] In collection2 [, ... ] ]

Example:

Dim customersForRegion = From cust In customers

You can specify multiple From clauses in a query to identify multiple collections to be joined. When multiple collections are specified, they are iterated over independently, or you can join them if they are related. You can join collections implicitly by using the Select clause, or explicitly by using the Join or Group Join clauses. As an alternative, you can specify multiple range variables and collections in a single From clause, with each related range variable and collection separated from the others by a comma. The following code example shows both syntax options for the From clause.

Page 22: Linq

Techlink Infoware Pvt. Ltd. Page 22 of 335 Dec 2010

LINQ Training Visual Basic

Queries – From Clause Continue …

' Multiple From clauses in a query.Dim result = From var1 In collection1, var2 In collection2

' Equivalent syntax with a single From clause.Dim result2 = From var1 In collection1 _

From var2 In collection2

The From clause defines the scope of a query, which is similar to the scope of a For loop. Therefore, each element range variable in the scope of a query must have a unique name. Because you can specify multiple From clauses for a query, subsequent From clauses can refer to range variables in the From clause, or they can refer to range variables in a previous From clause. For example, the following example shows a nested From clause where the collection in the second clause is based on a property of the range variable in the first clause.

Dim allOrders = From cust In GetCustomerList() _ From ord In cust.Orders _ Select ord

Dim customersForRegion = From cust In customers _ Where cust.Region = region

Page 23: Linq

Techlink Infoware Pvt. Ltd. Page 23 of 335 Dec 2010

LINQ Training Visual Basic

LINQ to Dataset

Page 24: Linq

Techlink Infoware Pvt. Ltd. Page 24 of 335 Dec 2010

LINQ Training Visual Basic

LINQ to Dataset

Page 25: Linq

Techlink Infoware Pvt. Ltd. Page 25 of 335 Dec 2010

LINQ Training Visual Basic

Queering Dataset

Coverage AreasSingle-Table Queries (LINQ to DataSet)

Describes how to perform single-table queries.

Cross-Table Queries (LINQ to DataSet) Describes how to perform cross-table queries.

Querying Typed DataSets Describes how to query typed DataSet objects.

Language-Integrated Query (LINQ) queries work on data sources that implement the IEnumerable(Of T) interface or the IQueryable interface. The DataTable class does not implement either interface, so you must call the AsEnumerable method if you want to use the DataTable as a source in the From clause of a LINQ query.

Page 26: Linq

Techlink Infoware Pvt. Ltd. Page 26 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetSingle Table Queries

The following example gets all the online orders from the SalesOrderHeader table and outputs the order ID, order date, and order number to the console.

' Fill the DataSet.Dim ds As New DataSet()ds.Locale = CultureInfo.InvariantCulture

' See the FillDataSet method in the Loading Data Into a DataSet topic.FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = From order In orders.AsEnumerable() _ Where order.Field(Of Boolean)("OnlineOrderFlag") = True _ Select New With { _ .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _

.OrderDate = order.Field(Of DateTime)("OrderDate"), _ .SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _ }

For Each onlineOrder In query Console.Write("Order ID: " & onlineOrder.SalesOrderID) Console.Write(" Order date: " & onlineOrder.OrderDate) Console.WriteLine(" Order number: " & onlineOrder.SalesOrderNumber)Next

Page 27: Linq

Techlink Infoware Pvt. Ltd. Page 27 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetAccessing Values without using Field method

Dim products As DataTable = ds.Tables("Product")

Dim query = _ From product In products.AsEnumerable() _ Where product!Color IsNot DBNull.Value AndAlso product!Color = "Red" _ Select New With _ { _ .Name = product!Name, _ .ProductNumber = product!ProductNumber, _ .ListPrice = product!ListPrice _ }

For Each product In query Console.WriteLine("Name: " & product.Name) Console.WriteLine("Product number: " & product.ProductNumber) Console.WriteLine("List price: $" & product.ListPrice & vbNewLine)Next

Page 28: Linq

Techlink Infoware Pvt. Ltd. Page 28 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetAccessing Values using Field method

Dim products As DataTable = ds.Tables("Product")

Dim query = _ From product In products.AsEnumerable() _ Where product.Field(Of String)("Color") = "Red" _ Select New With _ { _ .Name = product.Field(Of String)("Name"), _ .ProductNumber = product.Field(Of String)("ProductNumber"), _ .ListPrice = product.Field(Of Decimal)("ListPrice") _ }

For Each product In query Console.WriteLine("Name: " & product.Name) Console.WriteLine("Product number: " & product.ProductNumber) Console.WriteLine("List price: $ " & product.ListPrice & vbNewLine)Next

Page 29: Linq

Techlink Infoware Pvt. Ltd. Page 29 of 335 Dec 2010

LINQ Training Visual Basic

Queering Dataset

Advantage of using Field method and SetField method

The Field method provides access to the column values of a DataRow and the SetField sets column values in a DataRow. Both the Field method and SetField method handle nullable types, so you do not have to explicitly check for null values as in the previous example. Both methods are generic methods, also, so you do not have to cast the return type.

Page 30: Linq

Techlink Infoware Pvt. Ltd. Page 30 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetCross-Table Queries

The Language-Integrated Query (LINQ) framework provides two join operators, Join and GroupJoin. These operators perform equi-joins: that is, joins that match two data sources only when their keys are equal. (By contrast, Transact-SQL supports join operators other than equals, such as the less than operator.) 

In relational database terms, Join implements an inner join. An inner join is a type of join in which only those objects that have a match in the opposite data set are returned.

The GroupJoin operators have no direct equivalent in relational database terms; they implement a superset of inner joins and left outer joins. A left outer join is a join that returns each element of the first (left) collection, even if it has no correlated elements in the second collection.

Page 31: Linq

Techlink Infoware Pvt. Ltd. Page 31 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetCross-Table Queries

Dim orders As DataTable = ds.Tables("SalesOrderHeader")Dim details As DataTable = ds.Tables("SalesOrderDetail")

Dim query = _ From order In orders.AsEnumerable() _ Join detail In details.AsEnumerable() _ On order.Field(Of Integer)("SalesOrderID") Equals _ detail.Field(Of Integer)("SalesOrderID") _ Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _ order.Field(Of DateTime)("OrderDate").Month = 8 _ Select New With _ { _ .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _ .SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _ .OrderDate = order.Field(Of DateTime)("OrderDate"), _ .ProductID = detail.Field(Of Integer)("ProductID") _ }

For Each order In query Console.WriteLine(order.SalesOrderID & vbTab & _ order.SalesOrderDetailID & vbTab & _ order.OrderDate & vbTab & _ order.ProductID)Next

Page 32: Linq

Techlink Infoware Pvt. Ltd. Page 32 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetQuerying Typed DataSets

A typed DataSet is a class that derives from a DataSet. As such, it inherits all the methods, events, and properties of a DataSet. Additionally, a typed DataSet provides strongly typed methods, events, and properties. This means you can access tables and columns by name, instead of using collection-based methods. Aside from the improved readability of the code, a typed DataSet also allows the Visual Studio .NET code editor to automatically complete lines as you type.

Additionally, the strongly typed DataSet provides access to values as the correct type at compile time. With a strongly typed DataSet, type mismatch errors are caught when the code is compiled rather than at run time.

Typed DataSets

LINQ to DataSet also supports querying over a typed DataSet. With a typed DataSet, you do not have to use the generic Field method or SetField method to access column data.  Property names are available at compile time because the type information is included in the DataSet. LINQ to DataSet provides access to column values as the correct type, so that type mismatch errors are caught when the code is compiled instead of at run time.

Page 33: Linq

Techlink Infoware Pvt. Ltd. Page 33 of 335 Dec 2010

LINQ Training Visual Basic

Queering DatasetQuerying Typed DataSets

Dim orders = ds.Tables("SalesOrderHeader")

Dim query = _ From o In orders _ Where o.OnlineOrderFlag = True _ Select New {SalesOrderID := o.SalesOrderID, _ OrderDate := o.OrderDate, _ SalesOrderNumber := o.SalesOrderNumber}

For Each Dim onlineOrder In query Console.WriteLine("{0}\t{1:d}\t{2}", _ onlineOrder.SalesOrderID, _ onlineOrder.OrderDate, _ onlineOrder.SalesOrderNumber)Next