LINQ_Hands_on_Lab

Embed Size (px)

Citation preview

  • 8/7/2019 LINQ_Hands_on_Lab

    1/31

    LINQ: Language Integrated QueryHands-on Lab

    November 2007For the latest information, please see www.microsoft.com/vstudio

  • 8/7/2019 LINQ_Hands_on_Lab

    2/31

    Page i

    Information in this document is subject to change without notice. The example companies,organizations, products, people, and events depicted herein are fictitious. No association withany real company, organization, product, person or event is intended or should be inferred.Complying with all applicable copyright laws is the responsibility of the user . Without limiting therights under copyright, no part of this document may be reproduced, stored in or introducedinto a retrieval system, or transmitted in any form or by any means (electronic, mechanical,photocopying, recording, or otherwise), or for any purpose, without the express writtenpermission of Microsoft Corporation.

    Microsoft may have patents, patent applications, trademarked, copyrights, or other intellectualproperty rights covering subject matter in this document. Except as expressly provided in anywritten license agreement from Microsoft, the furnishing of this document does not give you anylicense to these patents, trademarks, copyrights, or other intellectual property.

    2007 Microsoft Corporation. All rights reserved.

    Microsoft, MS-DOS, MS, Windows, Windows NT, MSDN, Active Directory, BizTalk, SQL Server,SharePoint, Outlook, PowerPoint, FrontPage, Visual Basic, Visual C++, Visual J++, Visual InterDev,Visual SourceSafe, Visual C#, Visual J#, and Visual Studio are either registered trademarks ortrademarks of Microsoft Corporation in the U.S.A. and/or other countries.

    Other product and company names herein may be the trademarks of their respective owners.

  • 8/7/2019 LINQ_Hands_on_Lab

    3/31

    Page ii

    Contents

    LAB 1: LINQ PROJECT: UNIFIED LANGUAGE FEATURES FOR OBJECT AND RELATIONAL QUERIES ...... 1 L

    ab Objective ......................... ............................ ......................... ............................ .......................... ............... 1 Exercise 1 LINQ for In-M emory Collectio n s .................................................................................................... 2 Task 1 Creati n g the LINQ Overview Solutio n .......................................................................................... 2 Task 2 Q ueryi n g a Ge neric List of In tegers ........................ ........................... .......................... ................... 2 Task 3 Q ueryi n g Structured Types ...................... ........................... .......................... ............................ ..... 4

    Exercise 2 LINQ to X ML: LINQ for XML docume n ts ....................... ............................. ......................... .......... 6 Task 1 Addi n g LINQ to X ML Support ........................................................................................................ 6 Task 2 Q ueryi n g by Readi ng in a n XML File ...................... ............................ ......................... ................... 6 Task 3 Q ueryi n g a n XML File .................................................................................................................... 7 Task 4 Tra n sformi n g XML Output ............................................................................................................. 8

    Exercise 3 LINQ to DataSet : LINQ for DataSet Objects ...................... ........................... .......................... ...... 9 Task 1 Addi n g DataSet Support ...................... ........................... ......................... ............................. ......... 9 Task 2 Creati n g a DataSet Add Desig n er File ...................................................................................... 10 Task 3 Creati n g a DataSet Usi n g the Desig ner..................................................................................... 10 Task 4 Q ueryi n g a DataSet ..................................................................................................................... 10

    Exercise 4 LINQ to S QL: LINQ for Co nn ected Databases............................................................................ 11 Task 1 Addi n g LINQ to S QL Support ........................ ........................... .......................... .......................... 12 Task 2 Creati n g Object Mappi n g Creati n g a n Object a n d Providi ng Attributes .................................. .... 12 Task 3 Creati n g Object Mappi n g Usi n g the Desig n er Add Desig n er File ....................... ..................... 13 Task 4 Creati n g Object Mappi n g Usi n g the Desig n er Create the Object View ......................... ........... 13 Task 5 Q ueryi n g usi n g Expressio n s ........................................................................................................ 14 Task 6 Modifyi n g Database Data ............................................................................................................ 15 Task 7 Calli ng Stored Procedures ........................................................................................................... 17 Task 8 Expa nding Q uery Expressio n s ..................................................................................................... 17

    Exercise 5 U n dersta n din g the Sta n dard Q uery Operators [Optio nal] ......................... ............................ ....... 19 Task 1 Q ueryi n g usi n g the Sta n dard Q uery Operators ............................................................................ 19 Task 2 Worki ng with the Select Operator ................................................................................................ 21 Task 3 Worki ng with the Where Operator ........................... ......................... ............................ ................ 22 Task 4 Worki ng with the Cou n t Operator ...................... ............................ ......................... ...................... 23 Task 5 Worki ng with the Min, Max , Sum , a nd Average Operators ......................... ........................... ........ 24 Task 6 Worki ng with the All a nd A n y operators ...................... ............................ ......................... ............. 25 Task 7 Worki ng with the ToArray a n d To List Operators ....................... ........................... ......................... 26

    Lab Summary ................................................................................................................................................ 28

  • 8/7/2019 LINQ_Hands_on_Lab

    4/31

    Page 1

    Lab 1: LINQ Project: Unified Language Features for Object andRelational QueriesThis lab provides a n in troductio n to the LINQ Project. The la n guage i n tegrated query framework for .NET ( LINQ ) is a set of la nguage exte n sio n s to C# a n d Visual Basic a nd a u n ified programmi n g modelthat exte n ds the . NET Framework to offer i n tegrated queryi ng for objects , databases , a nd X ML.

    In this lab , you will see how LINQ features ca n be used agai n st i n- memory collectio n s , XML docume n ts , a nd co nn ected databases. The lab e n ds with a n optio n al exercise that looks at the varioussta ndard query operators available for data ma n ipulatio n a nd extractio n .

    This lab makes exte n sive use of n ew la nguage features provided i n C# 3.0. Whe n first in troduced theyare poi n ted out; however for a more i n depth u ndersta ndin g of how these features work , refer to the C# 3.0 Language Specification Hands On Lab .

    Lab Objective

    Estimated time to complete this lab : 60 minutes

    The objective of this lab is to provide a clear u n dersta nding of the LINQ project. You will see how datama n ipulatio n ca n occur o n objects i n memory , XML files , datasets , a nd relatio n al databases. The n ewLINQ AP Is be n efit from In telliSe n se a n d full compile -time checki n g without resorti n g to stri n g -basedqueries. This lab touches o n basic LINQ tech n ologies , alo n g with database -specific LINQ to S QL, XML-specific LINQ to X ML, a nd dataset -specific LINQ to DataSets. A brief look at query operators is alsoin cluded.

    This lab uses the Northwi n d database a n d co nsists of the followi ng exercises :

    LINQ to Objects : LINQ for In-M emory Collectio n s

    LINQ to X ML: LINQ for X ML Docume n ts

    LINQ to DataSets : LINQ for Dataset Objects

    LINQ to S QL: LINQ for Co nn ected DatabasesU ndersta n ding theSta n dard Q uery Operators [Optio n al]

  • 8/7/2019 LINQ_Hands_on_Lab

    5/31

    Page 2

    Exercise 1 LINQ for In-Memory Collections

    In this exercise , you lear n how to query over object seque n ces. A n y collectio n supporti n g theSystem.Collections.Generic . IEnumerable in terface or the ge n eric i n terface

    IEnumerable is co n sidered a seque n ce a nd ca n be operated o n usi n g the new LINQ standard query operators . Sta n dard query operators allow programmers to co n struct queries i ncludi n gprojectio n s that create n ew types o n the fly. This goes ha n d -in- ha n d with type i n fere n ce , a new featurethat allows local variables to be automatically typed by their i n itializatio n expressio n .

    Task 1 Creating the LINQ Overview Solution

    1. Click the Start | Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008me n u comma n d.

    2 . Click the File | New | Project me n u comma n d.

    3 . In the New Project dialog box select the Visual C# Windows project type.

    4 . Select the Console Application template.5 . Provide a name for the n ew project by e n teri n g LINQ Overview i n the Name box.

    6 . Click OK .

    Task 2 Querying a Generic List of Integers

    1. In Solutio n Explorer , double click Program.cs

    2 . Create a new method that declares a populated collectio n of in tegers (put this method i n theProgram class) :

    class Program{

    static void Main( string [] args){}static void NumQuery(){

    var numbers = new int [] { 1, 4, 9, 16, 25, 36 };}

    }

    Notice that the left-hand side of the assignment does not explicitly mention a

    type; rather it uses the new keyword var . This is possible due to one of the new

    features of the C# 3.0 language, local variable type inference. This feature allows thetype of a local variable to be inferred by the compiler. In this case, the right-hand

    side creates an object of type Int32[]; therefore the compiler infers the type of the

    numbers variable to be Int32[]. This also allows a type name to be specified only

    once in an initialization expression.

  • 8/7/2019 LINQ_Hands_on_Lab

    6/31

    Page 3

    3 . Add the followi n g code to query the collectio n for eve n n umbers

    static void NumQuery(){

    var numbers = new int [] { 1, 4, 9, 16, 25, 36 };

    var evenNumbers = from p in numberswhere (p % 2) == 0select p;

    }

    In this step the right-hand side of the assignment is a query expression, another

    language extension introduced by the LINQ project. As in the previous step, type

    inference is being used here to simplify the code. The return type from a query may

    not be immediately obvious. This example returns

    System.Collections.Gene r ic.IEnume rab le ; move the mouse over the

    evenNumbers variable to see the type in Quick Info. Indeed, sometimes there will be

    no way to specify the type when they are created as anonymous types (which are

    tuple types automatically inferred and created from object initalizers). Type

    inference provides a simple solution to this problem.

    4 . Add the followi n g code to display the results :

    static void NumQuery()

    { var numbers = new int [] { 1, 4, 9, 16, 25, 36 };

    var evenNumbers = from p in numberswhere (p % 2) == 0select p;

    Console .WriteLine( "Result:" );foreach ( var val in evenNumbers)

    Console .WriteLine(val);}

    Notice that the foreach statement has been extended to use type inference as

    well.

    5 . Fin ally , add a call to the NumQuery method from the Main method :

    static void Main( string [] args){

    NumQuery();}

  • 8/7/2019 LINQ_Hands_on_Lab

    7/31

    Page 4

    6 . Press Ctrl+F5 to build a n d ru n the applicatio n . A co n sole wi n dow appears. As expected all eve n n umbers are displayed (the numbers 4 , 16 , a n d 36 appear i n the co n sole output).

    7 . Press a n y key to termi nate the applicatio n .

    Task 3 Querying Structured Types1. In this task , you move beyo nd primitive types a nd apply query features to custom structured

    types. Above the Program class declaratio n, add the followi ng code to create a Customer class :

    public class Customer {

    public string CustomerID { get ; set ; }public string City { get ; set ; }

    public override string ToString(){

    return CustomerID + "\t" + City;}

    }class Program

    Notice the use of another new C# language feature, auto-implemented properties.

    In the preceding code, this feature creates two properties with automatic backing

    fields. Also notice that no constructor has been declared. In earlier versions of C#,

    this would have required consumers to create an instance of the object using the

    default parameterless constructor and then set the fields explicitly as separate

    statements.

    2 . Within the Program class declaratio n, create the followi n g new method , which creates a list of customers (take n from the Northwi n d database) :

    static void Main( string [] args){

    NumQuery(); } static IEnumerable CreateCustomers(){

    return new List {

    new Customer { CustomerID = "ALFKI" , City = "Berlin" },new Customer { CustomerID = "BONAP" , City = "Marseille" },new Customer { CustomerID = "CONSH" , City = "London" },new Customer { CustomerID = "EASTC" , City = "London" },new Customer { CustomerID = "FRANS" , City = "Torino" },new Customer { CustomerID = "LONEP" , City = "Portland" },new Customer { CustomerID = "NORTS" , City = "London" },new Customer { CustomerID = "THEBI" , City = "Portland" }

  • 8/7/2019 LINQ_Hands_on_Lab

    8/31

    Page 5

    };}

    There are several interesting things to note about this code block. First of all,

    notice that the new collection is being populated directly within the curly braces.

    That is, even though the type is List, not an array, it is possible to use braces to

    immediately add elements without calling the Add method. Second, notice that the

    Customer elements are being initialized with a new syntax (known as object

    initializers).

    3 . Next query the collectio n for customers that live i n Lon do n . Add the followi n g query methodObjectQuery a nd add a call to it withi n the Main method (removi n g the call to StringQuery ).

    static void ObjectQuery(){var results = from c in CreateCustomers()

    where c.City == "London"select c;

    foreach ( var c in results)Console .WriteLine(c);

    }

    static void Main( string [] args){

    ObjectQuery();}

    Notice that again the compiler is using type inference to strongly type the results

    variable in the foreach loop.

    4 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the results , press a n y key totermi n ate the applicatio n .

    Three results are shown. As you can see, when using LINQ query expressions,

    working with complex types is just as easy as working with primitive types.

  • 8/7/2019 LINQ_Hands_on_Lab

    9/31

    Page 6

    Exercise 2 LINQ to XML: LINQ for XML documents

    LINQ to X ML is a n ew X ML DO M that takes adva n tage of the sta ndard query operators a n d exposes asimplified way to create X ML docume n ts a nd fragme n ts.

    In this exercise , you lear n how to read X ML docume n ts i n to the XDocume n t object , how to queryeleme n ts from that object , a n d how to create docume n ts a n d eleme n ts from scratch.

    Task 1 Adding LINQ to XML Support

    1. The project template used earlier takes care of addi n g refere n ces a nd usi ng directivesautomatically. In Solution Explorer , expa nd LINQ Overview | References a n d notice theSystem.Xml.Linq refere n ce. In Program.cs add the followi n g directive to use the LINQ to X ML n amespace :

    using System.Xml.Linq;

    Task 2 Querying by Reading in an XML File

    For this task , you will query over a set of customers to fi nd those that reside i n Londo n . However asthe set of customers i n creases , you are less likely to store that data i n a code file; rather you maychoose to store the i n formatio n in a data file , such as a n XML file. Eve n though the data source ischa n ging , the query structure remai n s the same.

    1. This exercise uses the followi n g XML file. Save the followi n g as Customers.xml in the \bi n \debugfolder located i n the curre n t Project folder (by default this should be i n \My Documents\Visual Studio 2008\Projects\ LINQ Overview\ LINQ Overview\bin\debug ):

    2 . Cha n ge the CreateCustomer method i n the Program class to read the data i n from the X ML file:

    static IEnumerable CreateCustomers(){

    return from c in XDocument .Load( "Customers.xml" )

    .Descendants( "Customers" ).Descendants()select new Customer{

    City = c.Attribute( "City" ).Value,CustomerID = c.Attribute( "CustomerID" ).Value

    };}

  • 8/7/2019 LINQ_Hands_on_Lab

    10/31

    Page 7

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n . Notice the output still o n ly co n tain s thosecustomers that are located i n Londo n . Now press a n y key to termi n ate the applicatio n .

    Notice the query remains the same. The only method that was altered was the

    CreateCustomers method.

    Task 3 Querying an XML File

    This task shows how to query data i n a n XML file without first loadi ng it in to custom objects. Supposeyou did not have a Customer class to load the X ML data i n to. In this task you ca n query directly o n theXML docume n t rather tha n on collectio n s as show n in Task 2.

    1. Add the followi n g method XMLQuery that loads the xml docume n t a n d pri n ts it to the scree n

    (also update Main to call then

    ew method):

    public static void XMLQuery(){

    var doc = XDocument .Load( "Customers.xml" );

    Console .WriteLine( "XML Document:\n{0}" ,doc);}

    static void Main( string [] args){

    XMLQuery();}

    2 . Press Ctrl+F5 to build a n d ru n the applicatio n . The e n tire X ML docume n t is now pri n ted to thescree n . Press a ny key to termi n ate the applicatio n .

    3 . Retur n to the XMLQuery method , a nd n ow ru n the same query as before a n d pri n t out thosecustomers located i n Lon do n .

    public static void XMLQuery() {

    var doc = XDocument .Load( "Customers.xml" );

    var results = from c in doc.Descendants( "Customer" )

    where c.Attribute( "City" ).Value == "London"select c;

    Console .WriteLine( "Results:\n" );foreach ( var contact in results)

    Console .WriteLine( "{0}\n" , contact);}

    4 . Press Ctrl+F5 to build a n d ru n the applicatio n . The e n tire X ML docume n t is n ow pri n ted to thescree n . Press a ny key to termi n ate the applicatio n .

  • 8/7/2019 LINQ_Hands_on_Lab

    11/31

    Page 8

    M ove the mouse over either c or cont a ct to notice that the objects returned from

    the query and iterated over in the foreach loop are no longer Customers (like they are

    in the ObjectQuery method). Instead they are of type XElement. By querying theXM L document directly, there is no longer a need to create custom classes to store

    the data before performing a query.

    Task 4 Transforming XML Output

    This task walks though tra n sformi n g the output of your previous query i n to a n ew X ML docume n t.

    Suppose you wa n ted to create a new xml file that o n ly co n tai ned those customers located i n Londo n .In this task you write this to a differe n t structure tha n the Customers.xml file; each customer eleme n tstores the city a n d n ame as desce n de n t eleme n ts rather tha n attributes.

    1. Add the followi n g code that iterates through the results a nd stores them i n this n ew format.

    public static void XMLQuery(){

    XDocument doc = XDocument .Load( "Customers.xml" );

    var results = from c in doc.Descendants( "Customer" )where c.Attribute( "City" ).Value == "London"select c;

    XElement transformedResults =new XElement ( "Londoners" ,

    from customer in resultsselect new XElement ( "Contact" ,

    new XAttribute ( "ID" , customer.Attribute( "CustomerID" ).Value),new XElement ( "Name" , customer.Attribute( "ContactName" ).Value),new XElement ( "City" , customer.Attribute( "City" ).Value)));

    Console .WriteLine( "Results:\n{0}" , transformedResults);}

    H ere a temporary variable, results, was used to store the information returned

    from the query before altering the structure of the returned data.

    2 . Press Ctrl+F5 to build a n d ru n the applicatio n . The new X ML docume n t is pri n ted. Notice thesame data is retur n ed , just structured differe n tly. Press a n y key to termi nate the applicatio n .

    3 . Save the output to a file allowi n g the results of the query to be exported. To do this add thefollowing line of code.

    public static void XMLQuery(){

    XDocument doc = XDocument .Load( "Customers.xml" );

    var results = from c in doc.Descendants( "Customer" )where c.Attribute( "City" ).Value == "London"select c;

    XElement transformedResults =

  • 8/7/2019 LINQ_Hands_on_Lab

    12/31

    Page 9

    new XElement ( "Londoners" , from customer in results select new XElement ( "Contact" ,

    new XAttribute ( "ID" , customer.Attribute( "CustomerID" ).Value), new XElement ( "Name" , customer.Attribute( "ContactName" ).Value),

    new XElement ( "City" , customer.Attribute( "City" ).Value)));

    Console .WriteLine( "Results:\n{0}" , transformedResults); transformedResults.Save( "Output.xml" );

    } 4 . Press Ctrl+F5 to build a n d ru n the applicatio n . The new X ML docume n t is pri n ted to the scree n

    a nd writte n to a file that ca n be located where you placed your Customers.xml file. Now thedata ca n be exported as X ML to a n other applicatio n . Last , press a n y key to termi nate theapplicatio n .

    Exercise 3 LINQ to DataSet: LINQ for DataSet Objects

    This exercise demo n strates that the same features available for queryi ng in- memory collectio n s a ndqueryi n g xml ca n be applied to datasets.

    Stro ngly typed dataSets (a key eleme n t of the ADO. NET programmi n g model) provide a stro n gly typedreprese n tatio n of a set of tables a nd relatio n ships that is disco nn ected from a database. Thesedatasets have the ability to cache data from a database a n d allow applicatio n s to ma n ipulate the data i n memory while retai n ing its relatio nal shape.

    LINQ to DataSet provides the same rich query capabilities show n in LINQ to Objects a n d LINQ to XML.

    In this task you explore how to load i n datasets a nd create basic queries over the dataset.

    This exercise requires the Northwind database. Please follow the instructions in the LINQ toSQL section of the Essence of LINQ paper to get set up with Northwind before proceeding.

    Task 1 Adding DataSet Support

    1. The project template used earlier takes care of addi n g refere n ces a nd usi ng directivesautomatically. In Solution Explorer , expa nd LINQ Overview | References a n d notice theSystem.Data refere n ce. In Program.cs add the followi n g directive to use the DataSet

    n amespace : using System.Data.SqlClient;

    2 . You also need to add support for loadi n g co n figuratio n in formatio n from the app.co n fig file. Thesupport for this fu nctio n ality is available i n the System.Configuration assembly. In SolutionExplorer , right -click LINQ Overview | References a n d choose Add Reference .

    3 . Choose System.Configuration from the list that appears.

    4 . Click OK .

  • 8/7/2019 LINQ_Hands_on_Lab

    13/31

    Page 10

    5 . In Program.cs add the followi n g directive to use the Co n figuratio n namespace :

    using System.Configuration;

    Task 2 Creating a DataSet Add Designer File

    While creati ng datasets is n ot new to LINQ, these first few tasks lead you through creatio n of a datasetto set up a framework i n which to demo n strate LINQ to DataSet.

    1. Create the DataSet item. Right -click the LINQ Overview project a n d the n click Add | New Item .

    2 . In Templates, select DataSet.

    3 . Provide a name for the n ew item by e n teri n g Northwi ndDS i n the Name box.

    4 . Click OK.

    Task 3 Creating a DataSet Using the Designer

    1. In Server Explorer, expa n d Data Connections .

    2 . Ope n the Northwind server ( NORTHWND.MDF if you are usi n g S QL Server Express).

    3 . Ope n the Tables folder.

    4 . Ope n the NorthwindDS.xsd file by double clicki ng it from the Solution Explorer.

    5 . From the tables folder drag the Customers table o n to the desig n surface.

    6 . If prompted about movi n g the data file i n to the project folder , choose No .

    7 . Press Ctrl+Shift+B to build the applicatio n .

    Task 4 Querying a DataSet

    1. Retur n to the CreateCustomer method a n d update it to read data i n from the Northwi n d DataSetcreated by the desig n er ( n otice the retur n type also has to cha n ge) :

    static NorthwindDS . CustomersDataTable CreateCustomers(){

    SqlDataAdapter adapter = new SqlDataAdapter ("select * from customers" ,ConfigurationManager .ConnectionStrings[ "LINQOverview.Properties.Settings.NORTHWNDConnectionString" ].ConnectionString);

    NorthwindDS . CustomersDataTable table =new NorthwindDS . CustomersDataTable ();

    adapter.Fill(table);

    return table;}

    2 . We need to replace the co nn ectio n stri ng key i n the code above(LINQOverview.Properties.Settings.NORTHWNDConnectionString ), with the actual keyused i n the app.config file. In Solution Explorer , double -click the app.config file.

  • 8/7/2019 LINQ_Hands_on_Lab

    14/31

    Page 11

    3 . Un der the < connectionStrings > n ode , you will see a n n ode. Withi n this n ode , theco nn ectio n stri ng key is the value i n quotes after name= . Copy this quoted value.

    4 . Retur n to Program.cs a n d paste the key youve copied i n place of LINQOverview.Properties.Settings.NORTHWNDConnectionString in the body of the

    CreateCustomers method.5 . Retur n to the ObjectQuery method. You will need to make o ne update to the pri n t stateme n t

    (a n d update Main to call ObjectQuery agai n ):

    static void ObjectQuery(){

    var results = from c in CreateCustomers()where c.City == "London"select c;

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.CustomerID, c.City);

    }

    static void Main( string [] args){

    ObjectQuery();}

    M ove the mouse over c to notice that the objects returned from the query and

    iterated over in the foreach loop are no longer Customers, rather they are

    Custome rR ows . These objects are defined in the DataSet and are a strongly typed view

    of the Customer Table in the Northwind Database.

    6 . Press Ctrl+F5 to build a n d ru n the applicatio n . Notice the output still o n ly co n tain s thosecustomers that are located i n Londo n . Press a n y key to termi n ate the applicatio n .

    Exercise 4 LINQ to SQL: LINQ for Connected Databases

    This exercise begi n s by demo n strati n g that the same features available for queryi ng in- memorycollectio n s , xml files , a n d data sets , ca n also be applied to databases. The exercise the n co n tinues to

    show more adva n ced features available i n LINQ to S QL .LINQ to S QL is part of the LINQ project a nd allows you to query a n d ma n ipulate objects associatedwith database tables. It elimi n ates the traditio nal mismatch betwee n database tables a n d your applicatio n s domai n specific object model , freei n g you to work with data as objects while theframework ma nages retrievi n g a n d updati ng your objects.

    To create a n object model of a give n database , classes must be mapped to database e n tities. Thereare three ways to create object mappi n gs : addi n g attributes to a n existi n g object , usi ng the provided

  • 8/7/2019 LINQ_Hands_on_Lab

    15/31

    Page 12

    desig n er to auto -ge n erate the objects a nd mappi n gs , a n d usi n g the comma n d lin e S QLM etal tool. Thisexercise walks through the first two of these three methods.

    This exercise requires the Northwind database. Please follow the instructions in the LINQ toSQL section of the Essence of LINQ paper to get set up with Northwind before proceeding.

    Task 1 Adding LINQ to SQL Support

    1. You need to add support for LINQ to S QL to your project. The support for this fu n ctio nality isavailable i n the System.Data.Linq assembly. In Solution Explorer , right -click LINQ Overview |References a nd choose Add Reference .

    2 . Choose System.Data.Linq from the list that appears.

    3 . Click OK .

    4 . In Program.cs add the followi n g directive to use the Co n figuratio n namespace :

    using System.Data.Linq;using System.Data.Linq.Mapping;

    Task 2 Creating Object Mapping Creating an Object and Providing Attributes

    1. Add the followi n g attributes for Customer to create the mappi ng to the database Customers tablethat i n cludes colum n s named Customer ID a n d City. Here you will o n ly map two colum n s in thesin gle Customers table i n Northwi n d.

    [ Table (Name = "Customers" )]public class Customer{

    [ Column ]public string CustomerID { get ; set ; }[ Column ]public string City { get ; set ; }

    public override string ToString(){

    return CustomerID + "\t" + City;}

    }

    2 . Retur n to the ObjectQuery method. As you did for i n- memory collectio n s , XML, a n d DataSet , agai n query to fi nd customers that live i n Lon do n . Notice that mi n imal cha n ges are required.After creati n g a data co nn ectio n you are able to get rows out of the Customers table a nd selectthose rows for customers that live i n Lon do n, retur n in g them as IEnumerable .

    static void ObjectQuery(){

    var db = new DataContext( @"Data Source=.\sqlexpress;Initial Catalog=Northwind" );

    var results = from c in db.GetTable< Customer >()

  • 8/7/2019 LINQ_Hands_on_Lab

    16/31

    Page 13

    where c.City == "London"select c;

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.CustomerID, c.City);

    }

    The DataContext object used in the ObjectQuery method is the main conduit

    through which objects are retrieved from the database and changes are submitted.

    3 . Y ou need to replace the connection string here with the correct string for your specificconnection to Northwind. If youve do ne the previous exercise about LINQ to DataSet , you ca n fin d this stri n g in the ge n erated app.config file in the project. You will see later that after ge n erati n g stro n gly typed classes with the desig n er , it is n ot n ecessary to embed the co nn ectio n stri n g directly i n your code like this.

    4 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the results press a n y key to

    termin

    ate the application

    .5 . Now add the followi ng line to pri n t the ge nerated S QL query that ru n s o n the database :

    static void ObjectQuery(){

    DataContext db = new DataContext( @"Data Source=.\sqlexpress;Initial Catalog=Northwind" );

    db.Log = Console .Out;var results = from c in db.GetTable< Customer >()

    where c.City == "London"select c;

    foreach ( var c in results) Console .WriteLine( "{0}\t{1}" , c.CustomerID, c.City);

    }

    6 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the results a n d the ge n erated S QL query , press a n y key to termi n ate the applicatio n .

    Task 3 Creating Object Mapping Using the Designer Add Designer File

    1. First remove the old mappi ng. Delete the e n tire Customer class.

    2 . Next , create objects to model the tables. Right click the LINQ Overview project a nd click Add |New Item .

    3 . In Templates click LINQ To SQL Classes.

    4 . Provide a name for the n ew item by e n teri n g Northwi nd in the Name box

    5 . Click OK.

    Task 4 Creating Object Mapping Using the Designer Create the Object View

    1. Expa n d Data Connections in Server Explorer.

    2 . Ope n the Northwind server ( NORTHWND.MDF if you are usi n g S QL Server Express).

  • 8/7/2019 LINQ_Hands_on_Lab

    17/31

    Page 14

    3 . Ope n the Northwind.dbml file by double clicki n g it i n Solutio n Explorer.

    4 . From the Tables folder drag the Customers table o n to the desig n surface.

    5 . From the Tables folder drag the Products table o n to the desig n surface.

    6 . From the Tables folder drag the Employees table o n to the desig n surface.7 . From the Tables folder drag the Orders table o n to the desig n surface.

    8 . From the Stored Procedures folder drag the Ten Most Expensive Products in to the methodpa n e o n the right.

    5 . Press Ctrl+Shift+B to build the applicatio n . Take a look at the auto -ge n erated mappi n g class , Northwind.designer.cs . Notice a similar use of the attributes o n the ge nerated Customer class.

    For databases with many tables and stored procedures, using the command line

    tool SQL M etal provides more automation and may be a better choice.

    Task 5 Querying using Expressions

    1. Retur n to the program code file by double clicki n g o n the Program.cs file in Solution Explorer.Fin d the ObjectQuery method. Each table ca n n ow be accessed as a property of the dbvariable. At this poi n t, queryi n g is almost ide n tical to the previous exercises. Add the followi n gcode to retrieve customers i n Londo n:

    static void ObjectQuery(){

    var db = new NorthwindDataContext ();db.Log = Console .Out; var results = from c in db.Customers

    where c.City == "London"select c;

    foreach ( var c in results) Console .WriteLine( "{0}\t{1}" , c.CustomerID, c.City);

    }

    This creates a NorthwindDataContext object (which extends the DataContex t class

    previously used in the first task) that represents the strongly typed connection to the

    database. As such it is important to note that there is no connection string specified

    and intellisense shows all the tables specified by the designer.

    2 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the results , press a n y key totermi n ate the applicatio n .

    Six results are shown. These are customers in the Northwind Customers table with

    a City value of London.

  • 8/7/2019 LINQ_Hands_on_Lab

    18/31

    Page 15

    3 . You also created mappi ngs to other tables whe n usi n g the desig n er. The Customer class has aone -to -ma n y mappi n g to Orders. This n ext query selects from multiple tables.

    static void ObjectQuery(){var db = new NorthwindDataContext ();db.Log = Console .Out;var results = from c in db.Customers

    from o in c.Orderswhere c.City == "London"select new { c.ContactName, o.OrderID };

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.ContactName, c.OrderID);

    }

    The select statement creates a new object with an anonymous type (a new C# 3.0

    feature). The type created holds two pieces of data, both strings with the names of

    the properties of the original data (in this case Cont a ctN a me and Ord e r ID ). Anonymous

    types are quite powerful when used in queries. By using these types it saves the

    work of creating classes to hold every type of result created by various queries.

    In the preceding example, the object model can easily be seen by noticing the

    object relationship shown by writing c.O rd e r s . This relationship was defined in the

    designer as a one-to-many relationship and now can be accessed in this manner.

    4 . Press Ctrl+F5 to build a n d ru n the applicatio n to view the results. The n press a n y key totermi n ate the applicatio n .

    Task 6 Modifying Database Data

    In this task , you move beyo nd data retrieval a nd see how to ma n ipulate the data. The four basic dataoperatio n s are Create , Retrieve , Update , a n d Delete , collectively referred to as CRUD. You see howLINQ to S QL makes CRUD operatio n s simple a nd in tuitive. This task shows how to use the create a n dupdate operatio n s.

    5 . Create a new method that modifies the database data as well as a call from Main :

    static void ModifyData(){

    var db = new NorthwindDataContext ();

    Console .WriteLine( "Number Created Before: {0}" ,db.Customers.Where( c => c.CustomerID == "ADVCA" ).Count());

  • 8/7/2019 LINQ_Hands_on_Lab

    19/31

    Page 16

    var newCustomer = new Customer {

    CompanyName = "AdventureWorks Cafe" , CustomerID = "ADVCA"

    }; db.Customers.InsertOnSubmit(newCustomer);db.SubmitChanges();

    Console .WriteLine( "Number Created After: {0}" ,db.Customers.Where( c => c.CustomerID == "ADVCA" ).Count());

    }

    static void Main( string [] args){

    ModifyData();}

    6 . Press Ctrl+F5 to build a n d ru n the applicatio n . Notice that the two li nes writte n to the scree n arediffere n t after the database is updated. Now press a n y key to termi n ate the applicatio n .

    Notice that after the Add method is called, the changes are then submitted to the

    database using the SubmitChanges method. Note that once the customer has been

    inserted, it cannot be inserted again due to the primary key uniqueness constraint.

    Therefore this program can only be run once.

    7 . Now update a n d modify data i n the database. Cha nge ModifyData to the followi ng code thatupdates the co n tact n ame for the first customer retrieved.

    static void ModifyData() {

    var db = new NorthwindDataContext ();

    Console .WriteLine( "Number Updated Before: {0}" ,db.Customers.Where( c => c.ContactName == "New Contact" ).Count());

    var existingCustomer = db.Customers.First(); existingCustomer.ContactName = "New Contact" ;db.SubmitChanges();

    Console .WriteLine( "Number Updated After: {0}" ,db.Customers.Where( c => c.ContactName == "New Contact" ).Count());

    }

    8 . Now press Ctrl+F5 to build a nd ru n the applicatio n . Notice agai n the n umber of co n tacts with then ame New Co n tact cha n ges. Press a n y key to termi n ate the applicatio n .

  • 8/7/2019 LINQ_Hands_on_Lab

    20/31

    Page 17

    Task 7 Calling Stored Procedures

    Recall that whe n usi n g the desig n er , you added a stored procedure alo ng with the tables. In this taskyou will call tha stored procedure.

    1. Create a new method that pri n ts the results of a call to the Ten Most Expensive Products storedprocedure that was added to the Northwi ndDataCo n text i n the desig n er :

    static void InvokeSproc(){

    var db = new NorthwindDataContext ();foreach ( var r in db.Ten_Most_Expensive_Products())

    Console .WriteLine(r.TenMostExpensiveProducts + "\t" + r.UnitPrice);}

    2 . Now call this method from the Main method :

    static void Main( string [] args){

    InvokeSproc();}

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the results , press a n y key totermi n ate the applicatio n .

    W hen the database cannot be accessed through dynamic SQL statements, you can

    use C# 3.0 and LINQ to run stored procedures to access the data.

    Task 8 Expanding Query Expressions

    1. So far , the queries demo n strated i n this lab have bee n primarily based o n filterin g. However , LINQ supports ma n y optio n s for queryi ng data that go beyo n d simple filteri ng. For example , tosort customers i n Lon do n by Co n tact Name , you ca n use the orderby clause (also be sure to setthe Main method to call ObjectQuery agai n ):

    static void ObjectQuery(){

    var db = new NorthwindDataContext ();db.Log = Console .Out;var results = from c in db.Customers

    where c.City == "London"orderby c.ContactName descending select new { c.ContactName, c.CustomerID };

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.CustomerID, c.ContactName);

    }

  • 8/7/2019 LINQ_Hands_on_Lab

    21/31

    Page 18

    static void Main( string [] args){

    ObjectQuery();}

    2 . Press Ctrl+F5 to build a n d ru n the applicatio n . Notice the customers are sorted by the seco n dcolum n, the n ame colum n, in a desce nding ma nn er. Press a n y key to termi nate the applicatio n .

    3 . Co n tin ue with differe n t types of queries : write a query that fi nds the n umber of customers locatedin each city. To do this make use of the group by expressio n .

    static void ObjectQuery(){

    var db = new NorthwindDataContext ();db.Log = Console .Out;var results = from c in db.Customers

    group c by c.City into gorderby g.Count() ascending select new { City = g.Key, Count = g.Count() };

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.City, c.Count);

    }

    4 . Press Ctrl+F5 to ru n the applicatio n . After viewi ng the results , press a n y key to termi n ate theapplicatio n .

    5 . Ofte n whe n writin g queries you wa n t to search through two tables. This is usually performedusi n g a join operatio n, which is supported i n C# 3.0. In ObjectQuery replace the previous querywith this o n e. Recall your query pri n ted out all orders for each customer that lives i n Lon do n .

    This time , in stead of pri n ting all the orders , prin t the number of orders per customer.

    static void ObjectQuery(){

    var db = new NorthwindDataContext ();db.Log = Console .Out;var results = from c in db.Customers

    join e in db.Employees on c.City equals e.Citygroup e by e.City into gselect new { City = g.Key, Count = g.Count() };

    foreach ( var c in results)Console .WriteLine( "{0}\t{1}" , c.City, c.Count);

    }

  • 8/7/2019 LINQ_Hands_on_Lab

    22/31

    Page 19

    6 . Press Ctrl+F5 to ru n the applicatio n . Taki n g a look at the output , the S QL query ge n erated ca n also be see n . Press a n y key to termi nate the applicatio n .

    This example illustrates how a SQL style join can be used when there is no explicit

    relationship to navigate.

    Exercise 5 Understanding the Standard Query Operators [Optional]

    LINQ provides more tha n forty differe n t query operators , of which o n ly a small sample are highlightedhere. Additio nal operators ca n also be added programmatically through the sta n dard query operator AP Is.

    In this exercise , you lear n about several of the query operators available for data access a ndma n ipulatio n . These operators are a set of methods that every LINQ provider should impleme n t.

    Task 1 Querying using the Standard Query Operators

    1. The query expressio n sy n tax show n in previous examples (expressio n s starti ng with from) is notthe o n ly method of queryi n g data usi n g LINQ . LINQ in troduces various methods k now n as queryoperators that form the basis of the query expressio n fun ctio n ality youve see n, which you ca n also access directly i n a more familiar method -based way. Create a n ew method for thisexercise :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var matchingCustomers = db.Customers.Where(c => c.City.Contains( "London" ));

    foreach ( var c in matchingCustomers)Console .WriteLine( "{0}\t{1}\t{2}" ,

    c.CustomerID, c.ContactName, c.City);}

    static void ObjectQuery(){

    The parameter passed to the W here method is known as a lambda expression,

    another feature introduced in C# 3.0. Lambda expressions are shorthand for defininga function in-line, similar to anonymous methods in C#2.0. The first token "c"

    represents the current element of the sequence, in this case the Customers table. The

    => token means substitute c in the expression body, and the

    c.City.Contains("London") expression acts as the where clause. In LINQ to SQL this

    expression is emitted as an expression tree, which LINQ to SQL uses to construct the

    equivalent SQL statement at runtime.

  • 8/7/2019 LINQ_Hands_on_Lab

    23/31

    Page 20

    2 . Call this method from Main :

    static void Main( string [] args){

    OperatorQuery();}

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n . The n press a n y key to termi n ate the applicatio n .

    Notice that little has changed in this example. The query is now calling the

    standard query operators directly, but the result is the same as previous queries that

    selected only those customers that live in London.

    4 . Data aggregatio n ca n be obtai n ed by simply calli ng the sta n dard query operators o n the result , just as you would with a n y other method. Replace the code i n OperatorQuery to determi ne theaverage u n it price of all products starti n g with the letter "A" :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var avgCost = db.Products.Where(p => p.ProductName.StartsWith( "A" )).Select(p => p.UnitPrice).Average();

    Console .WriteLine( "Average cost = {0:c}" , avgCost);}

    5 . Press Ctrl+F5 to build a n d ru n the applicatio n . View the results a n d afterward press a n y key totermi n ate the applicatio n .

    The result now shows the average cost for products whose names start with "A".

    From left to right, first the table (db.Products) is specified and then the results are

    restricted to those rows with product names beginning with an "A". To this first

    filtered set of results two more operators are applied. Then the UnitPrice column is

    selected, getting back a collection of prices, one for each original result. Finally,

    using the Average operator the collection of prices are averaged and returned as a

    single value.

  • 8/7/2019 LINQ_Hands_on_Lab

    24/31

    Page 21

    Task 2 Working with the Select Operator

    1. The Select operator is used to perform a projectio n over a seque n ce , based o n the argume n tspassed to the operator. Source data are e numerated a nd results are yielded based o n theselector fu n ctio n for each eleme n t. The resulti n g collectio n ca n be a direct pass -through of thesource objects , a si ngle -field n arrowi ng , or a n y combi n atio n of fields i n a n ew object. Replace theprevious query to create a direct projectio n:

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var productsWithCh = from p in db.Productswhere p.ProductName.Contains( "Ch" )select p;

    }

    This query restricts the source data based on ProductName and then selects the

    entire Product.

    2 . Add the followi n g lines to create a si n gle -value projectio n:

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var productsWithCh = from p in db.Productswhere p.ProductName.Contains( "Ch" )

    select p;

    var productsByName = db.Products.Where(p => p.UnitPrice < 5).Select(p => p.ProductName);

    }

    This query restricts based on unit price and then returns a sequence of product

    names.

    3 . Add the followi n g lines to create a multi -value projectio n by usi n g a n a n on ymous type :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var productsWithCh = from p in db.Productswhere p.ProductName.Contains( "Ch" )select p;

    var productsByName = db.Products .Where(p => p.UnitPrice < 5)

  • 8/7/2019 LINQ_Hands_on_Lab

    25/31

  • 8/7/2019 LINQ_Hands_on_Lab

    26/31

    Page 23

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();}

    2 . The Where operator ca n be used to filter based o n predicates. E n ter the followi n g code to filter employees based o n employee birth dates :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var janBirthdays = db.Employees.Where(e => e.BirthDate.Value.Month == 1);

    foreach ( var emp in janBirthdays)Console .WriteLine( "{0}, {1}" , emp.LastName, emp.FirstName);

    }

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n a n d view the results. The n press a n y key totermi n ate the applicatio n .

    Task 4 Working with the Count Operator

    1. The Cou n t operator simply retur n s the number of eleme n ts i n a seque n ce. It ca n be applied to thecollectio n itself , or chai ned to other operators such as Where to cou n t a restricted seque n ce. Tosee how this works , in the Operator Q uery method , delete most of the body so it retur n s to asin gle comma n d:

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();}

    2 . Add the followi n g code to cou n t the n umber of eleme n ts i n the Customers table :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    int before = db.Customers.Count();int after1 = db.Customers.Where(c => c.City == "London" ).Count();int after2 = db.Customers.Count(c => c.City == "London" );

    Console .WriteLine( "Before={0}, After={1}/{2}" , before, after1, after2);}

  • 8/7/2019 LINQ_Hands_on_Lab

    27/31

    Page 24

    Take a look at the two different results (after1, and after2). Notice that restriction

    using W here can occur prior to Count being invoked, but it can also take effect

    directly within the call to Count.

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n a n d view the results before pressi n g a n y key totermi n ate the applicatio n .

    Task 5 Working with the Min, Max, Sum, and Average Operators

    1. In the Operator Q uery method , retur n to the Northwi n d database. Use the DataCo n text created

    by the desig n er : static void OperatorQuery(){

    var db = new NorthwindDataContext ();}

    2 . Add the followi n g lines of code to demo n strate the Min, Max , Sum , a n d Average operators :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var minCost = db.Products.Min(p => p.UnitPrice);var maxCost = db.Products.Select(p => p.UnitPrice).Max();var sumCost = db.Products.Sum(p => p.UnitsOnOrder);var avgCost = db.Products.Select(p => p.UnitPrice).Average();

    Console .WriteLine( "Min = {0:c}, Max = {1:c}, Sum = {2}, Avg = {3:c}" ,minCost, maxCost, sumCost, avgCost);

    }

    This example shows how the various aggregate math functions can be applied to

    data. You may have noticed that there are two signatures for the methods shown.

    M in and Sum are invoked directly on the db.Products object, while the M ax and

    Average operators are chained after Select operators. In the first case the aggregate

    function is applied just to the sequences that satisfy the expression while in the latter

    it is applied to all objects. In the end the results are the same.

  • 8/7/2019 LINQ_Hands_on_Lab

    28/31

    Page 25

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n . After viewi ng the latest results , press a n y key totermi n ate the applicatio n .

    As you can see, using these operators can considerably reduce code complexity.

    Task 6 Working with the All and Any operators

    1. The All a n d An y operators check whether a n y or all eleme n ts of a seque n ce satisfy a co n dition .The A n y operator retur ns results as soo n as a si ngle matchi n g eleme n t is fou n d. To see this i n actio n, in the Operator Q uery method , delete most of the body so it retur n s to a si n gle comma nd :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();}

    2 . Like the Cou n t operator , the A ll a n d A ny operators ca n be i n voked o n a n y co ndition, a nd their scope ca n be further restricted by specifyi n g a predicate at i n vocatio n . Add the followi n g code todemo n strate both operators :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();

    var customers1 = db.Customers.Where(c => c.Orders.Any());

    var customers2 = db.Customers.Where(c => c.Orders.All(o => o.Freight < 50));

    foreach ( var c in customers1)Console .WriteLine( "{0}" , c.ContactName);

    Console .WriteLine( "-----" );

    foreach ( var c in customers2)Console .WriteLine( "{0}" , c.ContactName);

    }

    Notice that in this case, the Any operator is used within the W here operator of

    another expression. This is perfectly legal as the operator is still being called on a

    sequence, c.Orders. This is used to return a sequence of all customers who have

    placed any orders. The All operator is then used to return customers whose orders

    have all had freight costs under $50.

  • 8/7/2019 LINQ_Hands_on_Lab

    29/31

    Page 26

    3 . Press Ctrl+F5 to build a n d ru n the applicatio n a n d view the results. The n press a n y key totermi n ate the applicatio n .

    Task 7 Working with the ToArray and ToList Operators

    1. The ToArray a n d To List operators are desig n ed to co n vert a seque n ce to a typed array or list , respectively. These operators are very useful for i n tegrati n g queried data with existi n g libraries of code. They are also useful whe n you wa n t to cache the result of a query. In the Operator Q uerymethod , delete most of the body so it has to a si n gle comma n d :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();}

    2 . Start by creati n g a seque n ce :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();var customers = db.Customers.Where(c => c.City == "London" );

    }

    Note that the sequence could be as simple as db.Customers. Restricting the

    results is not a necessary step to use ToArray or ToList.

    3 . Next , simply declare a n array or List collectio n, a nd assig n the proper values usi n g theappropriate operator :

    static void OperatorQuery(){

    var db = new NorthwindDataContext ();var customers = db.Customers.Where(c => c.City == "London" );

    Customer [] custArray = customers.ToArray();List custList = customers.ToList();

    foreach ( var cust in custArray)Console .WriteLine( "{0}" , cust.ContactName);

  • 8/7/2019 LINQ_Hands_on_Lab

    30/31

    Page 27

    foreach ( var cust in custList)Console .WriteLine( "{0}" , cust.ContactName);

    }

    4 . Press Ctrl+F5 to build a n d ru n the applicatio n a n d view the results. The n press a n y key totermi n ate the applicatio n .

  • 8/7/2019 LINQ_Hands_on_Lab

    31/31

    Lab Summary

    In this lab you performed the followi n g exercises :

    LINQ to Objects : LINQ for In-M emory Collectio n s

    LINQ to X ML: LINQ for X ML Docume n ts

    LINQ to DataSets : LINQ for Data Set Objects

    LINQ to S QL: LINQ for Co nn ected Databases

    Un dersta n ding the Sta n dard Q uery Operators [Optio nal]

    This lab showed how the LINQ framework a n d features seamlessly tie together data access a n dma n ipulatio n from a variety of sources. LINQ allows you to work with i n- memory objects with the power of S QL a n d the flexibility of C#. LINQ to S QL a nd LINQ to DataSets leverage this support to li n k your objects to database tables a n d data with little extra effort. Fi nally , LINQ to X ML brings X ML queryabilities with the features of XPath , but the ease of C#. The large collectio n of sta n dard queryoperators offers built -in optio n s for data ma n ipulatio n that would have required exte n sive custom codein theearlier versio n s. Usi ng the LINQ additio ns to C# , queryi n g a n d tra n sformi ng data i n a variety of formats is easier tha n ever.