csharp 3.0 and linq - 2007

Upload: jsanandkumar22

Post on 09-Apr-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    1/53

    DISTRIBUTED SYSTEMS RESEARCH GROUP

    http://nenya.ms.mff.cuni.cz

    CHARLES UNIVERSITY PRAGUE

    Faculty of Mathematics and Physics

    C# 3.0 and .NET 3.5: A BriefOverview

    Pavel Jeek

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    2/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    C# 3.0 Features

    Implicitly Typed Local Variables Extension Methods

    Lambda Expressions

    Object Initializers

    Collection Initializers

    Anonymous Types

    Expression Trees

    Query Expressions

    Beta versions of C# 3.0 compiler, libraries and Visual Studio 2005integration can be downloaded at:http://download.microsoft.com/download/4/7/0/4703eba2-78c4-4b09-8912-69f6c38d3a56/linq%20preview.msi

    .NET Framework 3.5 Beta 1:http://www.microsoft.com/downloads/details.aspx?FamilyId=E3715E6F-E123-428B-8A0F-028AFB9E0322&displaylang=en

    Visual Studio code name Orcas Beta 1:http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    3/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Implicitly Typed Local Variables

    Examples:var i = 5;var s = "Hello";var d = 1.0;var numbers = new int[] {1, 2, 3};var orders = new Dictionary();

    Are equivalent to:int i = 5;string s = "Hello";double d = 1.0;int[] numbers = new int[] {1, 2, 3};Dictionary orders = new Dictionary();

    Errors:

    var x; // Error, no initializer to infer type fromvar y = {1, 2, 3}; // Error, collection initializer not permittedvar z = null; // Error, null type not permitted

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    4/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Extension Methods

    Declaration:public static partial class Extensions {

    public static int ToInt32(this string s) {

    return Int32.Parse(s);

    }

    }

    Usage:

    string s = "1234";

    int i = s.ToInt32(); // Same as Extensions.ToInt32(s)

    Instance methods take precedence over extension methods Extension methods imported in inner namespace declarations take

    precedence over extension methods imported in outer namespace

    declarations

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    5/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Extension Methods (2)

    Declaration:public static partial class Extensions {

    public static T[] Slice(this T[] source, int index, int count) {if (index < 0 || count < 0 || source.Length index < count)

    throw new ArgumentException();T[] result = new T[count];Array.Copy(source, index, result, 0, count);return result;

    }}

    Usage:

    int[] digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    int[] a = digits.Slice(4, 3); // Same as Extensions.Slice(digits, 4, 3)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    6/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Lambda Expressions Example of C# 2.0 anonymous method:

    class Program {delegate T BinaryOp(T x, T y);

    static void Method(BinaryOp op, T p1, T p2) {

    Console.WriteLine(op(p1, p2));

    }

    static void Main() {

    Method(delegate(int a, int b) { return a + b; }, 1, 2);}

    }

    C# 3.0 lambda expressions provide further simplification:

    class Program {

    delegate T BinaryOp(T x, T y);

    static void Method(BinaryOp op, T p1, T p2) {

    Console.WriteLine(op(p1, p2));}

    static void Main() {Method((a, b) => a + b, 1, 2);

    }}

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    7/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Lambda Expressions (2)

    Expression or statement body Implicitly or explicitly typed parameters

    Examples:x => x + 1 // Implicitly typed, expression body

    x => { return x + 1; } // Implicitly typed, statement body

    (int x) => x + 1 // Explicitly typed, expression body

    (int x) => { return x + 1; } // Explicitly typed, statement body(x, y) => x * y // Multiple parameters

    () => Console.WriteLine() // No parameters

    A lambda expression is a value, that does not have a type but can beimplicitly converted to a compatible delegate type

    delegate R Func(A arg);

    Func f1 = x => x + 1; // Ok

    Func f2 = x => x + 1; // Ok

    Func f3 = x => x + 1; // Error double cannot be// implicitly converted to int

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    8/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Lambda Expressions (3)

    Lambda expressions participate in inference process of typearguments of generic methods

    In initial phase, nothing is inferred from arguments that are lambda

    expressions

    Following the initial phase, additional inferences are made from

    lambda expressions using an iterative process

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    9/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Lambda Expressions (4)

    Generic extension method example:public class List : IEnumerable, { }

    public static class Sequence {

    public static IEnumerable Select(

    this IEnumerable source,

    Func selector)

    {

    foreach (T element in source) yield return selector(element);

    }

    }

    Calling extension method with lambda expression:

    List customers = GetCustomerList();

    IEnumerable names = customers.Select(c => c.Name);

    Rewriting extension method call:

    IEnumerable names = Sequence.Select(customers, c => c.Name);

    T type argument is inferred to Customer based on source argument type

    Sequence.Select(customers, c => c.Name)

    c lambda expression argument type is infered to Customer

    Sequence.Select(customers, (Customer c) => c.Name)

    S type argument is inferred to string based on return value type of the lambda expression

    Sequence.Select(customers, (Customer c) => c.Name)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    10/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Object Initializers

    Class representing a point:public class Point {

    private int x, y;

    public int X { get { return x; } set { x = value; } }

    public int Y { get { return y; } set { y = value; } }

    }

    New instance can be created using object initializer:

    var a = new Point { X = 0, Y = 1 };

    Which is equivalent to:

    var a = new Point();

    a.X = 0;

    a.Y = 1;

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    11/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Object Initializers (2)

    Class representing a rectangle:

    public class Rectangle {private Point p1, p2;

    public Point P1 { get { return p1; } set { p1 = value; } }

    public Point P2 { get { return p2; } set { p2 = value; } }

    }

    New instance can be created using object initializer:

    var r = new Rectangle {P1 = new Point { X = 0, Y = 1 },

    P2 = new Point { X = 2, Y = 3 }

    };

    Which is equivalent to:

    var r = new Rectangle();

    var __p

    1 = new Point();__p1.X = 0;

    __p1.Y = 1;

    r.P1 = __p1;

    var __p2 = new Point();

    __p2.X = 2;

    __p2.Y = 3;

    r.P2 = __p2;

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    12/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Object Initializers (3)

    Class representing a rectangle with constructor that allocates p1 and p2:public class Rectangle {

    private Point p1 = new Point();

    private Point p2 = new Point();

    public Point P1 { get { return p1; } }

    public Point P2 { get { return p2; } }

    }

    New instance can be created using object initializer:

    var r = new Rectangle {

    P1 = { X = 0, Y = 1 },

    P2 = { X = 2, Y = 3 }

    };

    Which is equivalent to:

    var r = new Rectangle();

    r.P1.X = 0;

    r.P1.Y = 1;

    r.P2.X = 2;

    r.P2.Y = 3;

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    13/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Collection Initializers

    Example:List digits = new List { 0, 1, 2};

    Is equivalent to:

    List digits = new List();

    digits.Add(0);

    digits.Add(1);digits.Add(2);

    List has to implement System.Collections.Generic.ICollection interface with

    the Add(T) method

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    14/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Combining Object and Collection Initializers Class representing a contact with name and list of phone numbers:

    public class Contact {private string name;private List phoneNumbers = new List();

    public string Name { get { return name; } set { name = value; } }public List PhoneNumbers { get { return phoneNumbers; } }

    }

    List of contacts can be created and initialized with:var contacts = new List {

    new Contact {

    Name = "Chris Smith",PhoneNumbers = { "206-555-0101", "425-882-8080" }

    },

    new Contact {Name = "Bob Harris",PhoneNumbers = { "650-555-0199" }

    }};

    Which is equivalent to:var contacts = new List();var __c1 = new Contact();__c1.Name = "Chris Smith";

    __c1.PhoneNumbers.Add("206-555-0101");__c1.PhoneNumbers.Add("425-882-8080");contacts.Add(__c1);var __c2 = new Contact();__c2.Name = "Bob Harris";__c2.PhoneNumbers.Add("650-555-0199");contacts.Add(__c2);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    15/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Anonymous Types

    Following expression:new { p1 = e1 , p2 = e2 , pn = en }

    Can be used to define an anonymous type :

    class __Anonymous1 {

    private T1 f1 ;

    private T2 f2 ;

    private Tn fn ;

    public T1 p1 { get { return f1 ; } set { f1 = value ; } }

    public T2 p2 { get { return f2 ; } set { f2 = value ; } }

    public T1 p1 { get { return f1 ; } set { f1 = value ; } }

    }

    And create its instance using object initializer

    Different anonymous object initilizers that define properties with same names in the same ordergenerate the same anonymous type:

    var p1 = new { Name = "Lawnmower", Price = 495.00 };

    var p2 = new { Name = "Shovel", Price = 26.95 };

    p1 = p2;

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    16/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Expression Trees

    Permit lambda expressions to be represented as data structures instead ofexecutable code

    Lambda expression convertible to delegate D (assignment causes code generation)

    is also convertible to expression tree (abstract syntax tree) of type

    System.Query.Expression (assignment causes expression tree generation)

    Func f = x => x + 1; // Code

    Expression e = x => x + 1; // Data

    Full specification is not available yet (May 2006)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    17/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    ADO.NET: Connection-oriented Access

    1.) Declare connectiontry {

    1.) Request connection to database

    3.) Process result

    2.) Execute SQL commands

    4.) Release Resources

    } catch ( Exception ) {

    Handle exception

    } finally {

    try {4.) Close connection

    } catch (Exception)

    { Handle exception }

    }

    University of Linz, Institute for System Software, 2004

    published under the Microsoft Curriculum License(http://www.msdnaa.net/curriculum/license_curriculum.aspx)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    18/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    ADO.NET Example: EmployeeReader (1)

    using System;

    using System.Data;using System.Data.OleDb;

    public class EmployeeReader {

    public static void Main() {

    string connStr = "provider=SQLOLEDB; data source=(local)\\NetSDK; " +"initial catalog=Northwind; user id=sa; password=; ";

    IDbConnection con = null; // declare connection object

    try {

    con = new OleDbConnection(connStr); // create connection object

    con.Open(); // open connection

    1) Declare and request connection to database

    // create SQL command

    IDbCommand cmd = con.CreateCommand();

    cmd.CommandText = "SELECT EmployeeID, LastName, FirstName +

    FROM Employees";

    // execute SQL command; result is an OleDbDataReader

    IDataReader reader = cmd.ExecuteReader();

    2) Execute SQL commands

    University of Linz, Institute for System Software, 2004

    published under the Microsoft Curriculum License(http://www.msdnaa.net/curriculum/license_curriculum.aspx)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    19/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    ADO.NET Example: EmployeeReader (2)

    IDataReader reader = cmd.ExecuteReader();object[] dataRow = new object[reader.FieldCount];

    while (reader.Read()) {

    int cols = reader.GetValues(dataRow);

    for(int i = 0; i < cols; i++) Console.Write("| {0} " , dataRow[i]);

    Console.WriteLine();

    }

    3) Read and process data rows

    reader.Close();

    } catch (Exception e) {

    Console.WriteLine(e.Message);

    } finally {

    try {

    if(con != null)

    // ----- close connection

    con.Close();

    } catch (Exception ex) { Console.WriteLine(ex.Message); }

    } } }

    4) Release resources and close connection

    University of Linz, Institute for System Software, 2004

    published under the Microsoft Curriculum License(http://www.msdnaa.net/curriculum/license_curriculum.aspx)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    20/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Query Expressions

    Query expressions or LINQ (Language INtergrated Queries) are the key feature of.NET 3.5

    Query expressions are translated to method calls works on classes like:

    delegate R Func(A arg);

    class C

    {

    public C Where(Func predicate);

    public C Select(Func selector);

    public C SelectMany(Func selector);public O OrderBy(Func keyExpr);

    public O OrderByDescending(Func keyExpr);

    public C GroupBy(Func keyExpr);

    p

    ublic C Group

    By(Func keyExp

    r, FuncelemExpr);

    }

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    21/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Query Expressions Examples

    Query expression:

    from c in customers where c.City == "London select c

    Gets translated to:

    customers.Where(c => c.City == "London")

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    22/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Query Expressions Examples

    Query expression:

    from c in customers where c.City == "London select c.Name

    Gets translated to:

    customers.Where(c => c.City == "London").Select(c => c.Name)

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    23/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Query Expressions Examples

    Query expression:

    from c in customers orderby c.Name select new { c.Name, c.Phone }

    Gets translated to:

    customers.OrderBy(c => c.Name).Select(c => new { Name = c.Name,Phone = c.Phone })

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    24/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    Query Expressions Examples

    Query expression:

    from c in customers

    where c.City == "London"

    from o in c.Orders

    where o.OrderDate.Year == 2005

    select new { c.Name, o.OrderID, o.Total }

    Gets translated to:

    customers.Where(c => c.City == "London").

    SelectMany(c =>

    c.Orders.

    Where(o => o.OrderDate.Year == 2005).Select(o => new {

    Name = c.Name, OrderID = o.OrderID, Total = o.Total})

    )

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    25/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    BCL Extended by Query Expressions

    Set of generic extension methods (Select, Where, OrderBy, + others) implemented for IEnumerable

    interface, example:

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

    var numberGroups = fromn in numbers group nby n % 5 into g

    select new {Remainder = g.Key, Numbers = g.Group};

    foreach (var g in numberGroups) {

    Console.WriteLine("Numbers with a remainder of {0} when divided by 5:", g.Remainder);

    );

    foreach (int n in g.Numbers) {

    Console.WriteLine(n);

    }

    }

    DLinq Classes for SQL data access using query expressions

    XLinq - Classes for XML data access using query expressions

    Numbers with a remainder of 0 when divided by 5:

    5

    0Numbers with a remainder of 4 when divided by 5:

    4

    9

    Numbers with a remainder of1 when divided by 5:

    1

    6

    Numbers with a remainder of3 when divided by 5:

    3

    8

    Numbers with a remainder of 2 when divided by 5:

    72

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    26/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Creating Entity Classes

    Only instances of entity classes, i.e. entities , can be stored in/retrieved from databases

    [Table] // Table is named Customerpublic class Customer

    {

    public string CustomerID; // Transient data not stored in DB

    public string City; // Transient data not stored in DB}

    [Table(Name="Customers")]

    public class Customer{

    public string CustomerID; // Transient data not stored in DB

    public string City; // Transient data not stored in DB}

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

    {

    [Column(Id=true)] // Part of database primary keypublic string CustomerID;

    [Column]

    public string City;

    }

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    27/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq - DataContext

    DataContextis equivalent of ADO.NET connection

    It retrieves data (objects) from the database and submits changes

    It translates requests (queries) for objects into SQL queries

    Using the DataContext to retrieve customer objects whose city is London:

    // DataContext takes a connection string

    DataContext db = new DataContext("c:\\northwind\\northwnd.mdf");

    // Get a typed table to run queriesTable Customers = db.GetTable();

    // Query for customers from Londonvar q = from c in Customers where c.City == "London select c;

    foreach (var cust in q) {Console.WriteLine("id = {0}, City = {1}", cust.CustomerID,cust.City);

    }

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    28/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Strongly Typed DataContext

    p

    ublicp

    artial class Northwind : DataContext{

    public Table Customers;

    public Table Orders;

    public Northwind(string connection): base(connection) {}

    }

    Retrieving customer objects whose city is London more easily:

    Northwind db = new Northwind("c:\\northwind\\northwnd.mdf");

    var q = from c in db.Customers where c.City == "London select c;

    foreach (var cust in q) {

    Console.WriteLine("id = {0}, City = {1}",cust.CustomerID,cust.City);}

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    29/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Query Execution

    Queries are not imperative they are not executed immediately

    var q = from c in db.Customerswhere c.City == "London"select c;

    Only creates an instance ofQuery type and assigns it to q

    When the application tries to enumerate the contents of a query, it gets executed

    (i.e. deferred execution):

    // Execute first timeforeach (Customer c in q) Console.WriteLine(c.CompanyName);

    // Execute second time

    foreach (Customer c in q) Console.WriteLine(c.CompanyName);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    30/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Advantage of Deferred Execution

    Partial query contruction:

    var q = from c in db.Customerswhere c.City == "London"select c;

    if (orderByLocation) {

    q = from c in qorderby c.Country, c.Cityselect c;

    } else if (orderByName) {

    q = from c in qorderby c.ContactNameselect c;

    }

    foreach (Customer c in q) Console.WriteLine(c.CompanyName);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    31/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Avoiding Deferred Execution

    Query can be converted to standard collection classes using ToList() orToArray() Standard Query Operators (or converted to DataSets DataTable usingToDataTable()) leads to immediate execution:

    var q = from c in db.Customerswhere c.City == "London"select c;

    // Execute once using ToList(), ToArray() or ToDataTable()var list = q.ToList();

    foreach (Customer c in list) Console.WriteLine(c.CompanyName);

    foreach (Customer c in list) Console.WriteLine(c.CompanyName);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    32/53

    Pavel Jeek

    C# 3.0 and .NET 3.5

    DLinq Defining Relationships

    [Table(Name="Customers")]

    public class Customer{

    [Column(Id=true)]public string CustomerID;...private EntitySet _Orders;[Association(Storage="_Orders", OtherKey="CustomerID")]

    public EntitySet Orders {get { return this._Orders; }

    set { this._Orders.Assign(value); }}

    }

    [Table(Name="Orders")]public class Order{

    [Column(Id=true)]

    public int OrderID;

    [Column]public string CustomerID;

    private EntityRef _Customer;

    [Association(Storage="_Customer", ThisKey="CustomerID")]public Customer Customer {

    get { return this._Customer.Entity; }set { this._Customer.Entity = value; }

    }}

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    33/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Querying Across Relationships

    Query using the Orders property to form the cross product between customers andorders, producing a new sequence of Customer and Order pairs:

    var q = from c in db.Customersfrom o in c.Orderswhere c.City == "London"select new { c, o };

    Another query producing the same result:

    var q = from o in db.Orderswhere o.Customer.City == "London"select new { c = o.Customer, o };

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    34/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Modifying Entities

    Northwind db = new Northwind("c:\\northwind\\northwnd.mdf");

    // Query for a specific customerstring id = "ALFKI";

    var cust = db.Customers.Single(c => c.CustomerID == id);

    // Change the name of the contactcust.ContactName = "New Contact";

    // Delete an existing Order

    Order ord0 = cust.Orders[0];

    // Removing it from the table also removes it from the Customers listdb.Orders.Remove(ord0);

    // Create and add a new Order to Orders collection

    Order ord = new Order { OrderDate = DateTime.Now };cust.Orders.Add(ord);

    // Ask the DataContext to save all the changes generates appropriate SQL command

    db.SubmitChanges();

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    35/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Creating Simple Databases

    [Table(Name="DVDTable")]

    public class DVD{

    [Column(Id = true)]public string Title;[Column]public string Rating;

    }

    public class MyDVDs : DataContext

    {public Table DVDs;public MyDVDs(string connection) : base(connection) {}

    }

    // Creating a new databaseMyDVDs db = new MyDVDs("c:\\mydvds.mdf");db.CreateDatabase();

    // Replacing an existing oneMyDVDs db = new MyDVDs("c:\\mydvds.mdf");

    if (db.DatabaseExists()) {db.DeleteDatabase();

    }

    db.CreateDatabase();

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    36/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Inheritance

    [Table]

    [InheritanceMapping(Code = "C", Type = typeof(Car))][InheritanceMapping(Code = "T", Type = typeof(Truck))]

    [InheritanceMapping(Code = "V", Type = typeof(Vehicle), IsDefault = true)]public class Vehicle {

    [Column(IsDiscriminator = true)]public string Key;[Column(Id = true)]public string VIN;[Column]

    public string MfgPlant;}

    public class Car : Vehicle {[Column]public int TrimCode;[Column]public string ModelName;

    }

    public class Truck : Vehicle {

    [Column]public int Tonnage;[Column]public int Axles;

    }

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    37/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Inheritance

    Example queries:

    var q = db.Vehicle.Where(p => p is Truck);

    var q = db.Vehicle.OfType();

    var q = db.Vehicle.Select(p => p as Truck).Where(p => p != null);foreach (Truck p in q)

    Console.WriteLine(p.Axles);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    38/53

    Pavel JeekC# 3.0 and .NET 3.5

    DLinq Query Visualizer in VS

    static void Main(string[] args) {Northwnd db = new Northwnd(@"C:\program files\linq preview\data\northwnd.mdf");

    var q =from c in db.Customerswhere c.City == "London"select c;

    } // Breakpoint

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    39/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Example XML

    Patrick Hines206-555-0144425-555-0145

    123 Main StMercer IslandWA68042

    10

    Gretchen Rivas206-555-0163

    123 Main StMercer IslandWA68042

    11

    Scott MacDonald925-555-0134425-555-0177

    345 Stewart StChatsworthCA91746

    500000

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    40/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Creating XML via DOM (without XLinq)

    XmlDocument doc = new XmlDocument();

    XmlElement name = doc.CreateElement("name");name.InnerText = "Patrick Hines";XmlElement phone1 = doc.CreateElement("phone");phone1.SetAttribute("type", "home");phone1.InnerText = "206-555-0144";XmlElement phone2 = doc.CreateElement("phone");phone2.SetAttribute("type", "work");phone2.InnerText = "425-555-0145";XmlElement street1 = doc.CreateElement("street1");street1.InnerText = "123 Main St";XmlElement city = doc.CreateElement("city");city.InnerText = "Mercer Island";XmlElement state = doc.CreateElement("state");state.InnerText = "WA";XmlElement postal = doc.CreateElement("postal");postal.InnerText = "68042";XmlElement address = doc.CreateElement("address");address.AppendChild(street1);address.AppendChild(city);address.AppendChild(state);address.AppendChild(postal);XmlElement contact = doc.CreateElement("contact");contact.AppendChild(name);

    contact.AppendChild(phone1);contact.AppendChild(phone2);contact.AppendChild(address);XmlElement contacts = doc.CreateElement("contacts");contacts.AppendChild(contact);doc.AppendChild(contacts);

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    41/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Creating XML via XLinq

    Functional construction:

    XElement contacts =

    new XElement("contacts",new XElement("contact",

    new XElement("name", "Patrick Hines"),new XElement("phone", "206-555-0144",

    new XAttribute("type", "home")),new XElement("phone", "425-555-0145",

    new XAttribute("type", "work")),

    new XElement("address",new XElement("street1", "123 Main St"),new XElement("city", "Mercer Island"),new XElement("state", "WA"),new XElement("postal", "68042")

    ))

    );

    Imlicitly no XML document Can be added if some processing information is needed:

    XDocument contactsDoc =new XDocument(

    new XDeclaration("1.0", "UTF-8", "yes"),new XComment("XLinq Contacts XML Example"),new XProcessingInstruction("MyApp", "123-44-4444"),

    new XElement("contacts",new XElement("contact",

    new XElement("name", "Patrick Hines"),

    Resulting XML:

    Patrick Hines

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    42/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq XML Namespaces

    There is a support for XML namespaces, but namespace aliases are always expanded into full names

    Creating element from a http://myCompany.com namespace:

    XElement contacts = new XElement("{http://myCompany.com}contacts", );

    Instead of explicit alias support, existing language facilities should be used. Typical pattern:

    string myNs = "{http://mycompany.com}";

    XElement contacts =new XElement(myNs+"contacts",

    new XElement(myNs+"contact",new XElement(myNs+"name", "Patrick Hines"),new XElement(myNs+"phone", "206-555-0144",

    new XAttribute("type", "home")),)

    ));

    Results in following XML:

    Patrick Hines206-555-0144

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    43/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Loading Existing XML Data

    From string:

    XElement contacts = XElement.Parse(@"

    Patrick Hines206-555-0144425-555-0145

    123 Main StMercer Island

    WA68042

    10

    ");

    From file:

    XElement contactsFromFile = XElement.Load(@"c:\myContactList.xml");

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    44/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Creating XElements

    XElements constructor:

    public XElement(XName name, params object[] contents)

    Any of the parameters passed to contents can be:

    1. A string, which is added as text content

    2. An XElement, which is added as a child element

    3. An XAttribute, which is added as an attribute

    4. An XProcessingInstruction, XComment, orXCData, which is added as child content5. An IEnumerable, which is enumerated, and these rules are applied recursively

    6. Anything else, ToString() is called and the result is added as text content

    7. null, which is ignored

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    45/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Adding IEnumerables to XElement

    class Person { public string Name; public string[] PhoneNumbers; }

    var persons = new [] {new Person { Name="Patrick Hines",

    PhoneNumbers = new string[] {"206-555-0144", "425-555-0145"} },

    new Person { Name="Gretchen Rivas",PhoneNumbers = new string[] {"206-555-0163"} }

    };

    Following code using Standard Query Operators on IEnumerable can be used to transform a datastructureto XML:

    XElement contacts =

    new XElement("contacts",fromp in persons

    select new XElement("contact",

    new XElement("name", p.Name),

    fromph in p.PhoneNumbers

    select new XElement("phone", ph))

    );

    Console.WriteLine(contacts);

    Output:

    Patrick Hines206-555-0144425-555-0145

    Gretchen Rivas206-555-0163

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    46/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLing Element Text as Value (1)

    XElement (text inside XElement) can be explicitly converted to a value:

    XElement name = new XElement("name", "Patrick Hines");

    string nameString = (string) name;

    Console.WriteLine(nameString);

    ToString() returns the XML representation of the whole element:

    string nameString = name.ToString();Console.WriteLine(nameString);

    Explicit type operators are provided for following types:string, bool, bool?, int, int?, uint, uint?, long, long?, ulong, ulong?, float,float?, double, double?, decimal, decimal?, DateTime, DateTime?, TimeSpan,TimeSpan?, GUID, GUID?

    Output:

    Patrick Hines

    Output:

    Patrick Hines

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    47/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLing Element Text as Value (2)

    All element text is merged together:

    XElement xhtml = new XElement(body",

    1234,

    new XElement("br", null),

    5678,

    "some text",

    new XElement("br", ""),

    new XElement("em", "EMPHASED TEXT"),"other text\nwith newline"

    );

    Console.WriteLine(nameString);

    Console.WriteLine((string) nameString);

    Output:

    1234
    5678some text
    EMPHASED TEXTother textwith newline

    Output:

    12345678some textEMPHASED TEXTother text

    with newline

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    48/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Traversing XML

    XML data:

    Met in 2005.Patrick Hines206-555-0144425-555-0145

    Code examples:

    foreach (c in contact.Content()) {Console.WriteLine(c);

    }

    foreach (c in contact.Content()) {Console.WriteLine(c)

    }

    foreach (x in contact.Elements()) {Console.WriteLine(x);

    }

    foreach (x in contact.Elements("phone")) {Console.WriteLine(x);

    }

    XElement name = contact.Element("name");

    string name = (string) contact.Element("name");

    Met in 2005.Patrick Hines206-555-0144425-555-0145

    Patrick Hines206-555-0144

    425-555-0145

    206-555-0144425-555-0145

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    49/53

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    50/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq - Queries Example flattening contacts:

    new XElement("contacts",from c in contacts.Elements("contact")select new object[] {

    new XComment("contact"),new XElement("name", (string)c.Element("name")),c.Elements("phone"),new XElement("address", c.Element("address"))

    });

    Results in:

    Patrick Hines206-555-0144425-555-0145

    WA

    Gretchen Rivas

    WA

    Scott MacDonald925-555-0134425-555-0177...

    Patrick Hines

    206-555-0144425-555-0145

    12

    Merce

    WA

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    51/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq Schema Aware programming

    Without schema:

    public static double GetTotalByZip(XElement root, int zip) {return (

    from order in root.Elements("order"),item in order.Elements("item"),

    where (int) order.Element("address").Element("postal") == zipselect ((double) price * (int) qty)

    ).Sum();

    }

    With schema (currently neither implemented nor specified probable XLinq extension in final version):

    public static double GetTotalByZip(Orders root, int zip) {return (

    from order in root.OrderCollection,item in order.Items

    where order.Address.Postal == zipselect (item.Price * item.Quantity)

    ).Sum();

    }

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    52/53

    Pavel JeekC# 3.0 and .NET 3.5

    XLinq in Visual Basic 9 (1)

    Using C# 3.0 functional approach:

    Dim contacts As XElement = _

    New XElement("contacts", _New XElement("contact", _New XElement("name", "Patrick Hines"), _

    New XElement("phone", "206-555-0144", _New XAttribute("type", "home")), _

    New XElement("phone", "425-555-0145", _New XAttribute("type", "work")), _

    New XElement("address", _New XElement("street1", "123 Main St"), _

    New XElement("city", "Mercer Island"), _New XElement("state", "WA"), _

    New XElement("postal", "98040"))))

    Using XML literals:

    Dim contacts As XElement = _

    Patrick Hines

    206-555-0144425-555-0145

    123 Main St

    Mercer IslandWA98040

  • 8/8/2019 Csharp 3.0 and LINQ - 2007

    53/53

    Pavel Jeek

    XLinq in Visual Basic 9 (2)

    Visual Basic expressions in XML literals:

    Dim myName = "Patrick HinesDim contact As XElement =

    Dim MyName = "Patrick HinesDim elementName = "contactDim contact As XElement =

    Late bound XML:

    For Each Dim phone In contact.phoneConsole.WriteLine(CStr(phone.@type))

    NextConsole.WriteLine(CStr(contacts...city(0)))

    For Each Dim phone In contact.Element("phone")Console.WriteLine(CStr(phone.Attribute("type")))

    NextConsole.WriteLine(CStr(ElementAt(contact.Descendants("city"),0)))