30

C# 3.0 & LINQ

  • Upload
    lyris

  • View
    41

  • Download
    1

Embed Size (px)

DESCRIPTION

C# 3.0 & LINQ. Raimond Brookman – IT Architect http://blogs.infosupport.com/raimondb. Outline. Linq Project DLinq XLinq C# 3.0 Language Enhancements. Problem: Data != Objects. Service based Solution. . Xml Read. - PowerPoint PPT Presentation

Citation preview

Page 1: C# 3.0 & LINQ
Page 2: C# 3.0 & LINQ

C# 3.0 & LINQ

Raimond Brookman – IT Architecthttp://blogs.infosupport.com/raimondb

Page 3: C# 3.0 & LINQ

Outline

- Linq Project- DLinq- XLinq- C# 3.0 Language Enhancements

Page 4: C# 3.0 & LINQ

Problem:Problem:Data != ObjectsData != Objects

Page 5: C# 3.0 & LINQ

Service based Solution

Customer Mgt Customer Mgt ServiceService

(HTTP + XML)(HTTP + XML)

WebWebApplicationApplication

Order MgtOrder MgtWSWS

Order ProcessingOrder ProcessingWSWS

ORM

Xml R/W

Databound grid

BR Check

TransformMsg

<book> <title/> <author/> <year/> <price/></book>

XML ConfigXML Config

XmlRead

Page 6: C# 3.0 & LINQ

The LINQ Project

StandardStandardQueryQuery

OperatorsOperators

ObjectsObjects

DLinqDLinq(ADO.NET)(ADO.NET)

XLinqXLinq(System.Xml)(System.Xml)

<book> <title/> <author/> <year/> <price/></book>

XMLXML

.NET Language Integrated Query.NET Language Integrated Query

C# 3.0C# 3.0 VB 9.0VB 9.0 Others…Others…

SQLSQL WinFWinFSS

Page 7: C# 3.0 & LINQ

Service based Solution with LINQ

Customer Mgt Customer Mgt ServiceService

(HTTP + XML)(HTTP + XML)

WebWebApplicationApplication

Order MgtOrder MgtWSWS

Order ProcessingOrder ProcessingWSWS

ORM

Xml R/W

Databound grid

BR Check

TransformMsg

<book> <title/> <author/> <year/> <price/></book>

XML ConfigXML Config

XmlRead

DLINQ

O-LINQ

O-LINQXLINQ

XLINQ

O-LINQ

Page 8: C# 3.0 & LINQ

LINQ Style programming

var contacts =var contacts = from c in customersfrom c in customers where c.State == "WA"where c.State == "WA" select new { c.Name, c.Phone };select new { c.Name, c.Phone };

class Contact { … };class Contact { … };List<Contact> contacts = new List<Contacts>();List<Contact> contacts = new List<Contacts>();foreach(Customer c in customers) foreach(Customer c in customers) {{

if(c.State == “WA”) if(c.State == “WA”) {{ Contact ct = new Contact();Contact ct = new Contact(); ct.Name = c.Name;ct.Name = c.Name; ct.Phone = c.Phone;ct.Phone = c.Phone; contacts.Add(ct);contacts.Add(ct);}}

}}

Page 9: C# 3.0 & LINQ

Query Expressions

Language integrated query syntax

fromfrom idid inin sourcesource{ { fromfrom idid inin sourcesource | | wherewhere conditioncondition } }[ [ orderbyorderby orderingordering, , orderingordering, … ], … ]selectselect exprexpr | | groupgroup exprexpr byby keykey[ [ intointo idid queryquery ] ]

Page 10: C# 3.0 & LINQ

Standard Query Operators

RestrictionRestriction WhereWhereProjectionProjection Select, SelectManySelect, SelectManyOrderingOrdering OrderBy, ThenByOrderBy, ThenByGroupingGrouping GroupByGroupByQuantifiersQuantifiers Any, AllAny, AllPartitioningPartitioning Take, Skip, TakeWhile, SkipWhileTake, Skip, TakeWhile, SkipWhileSetsSets Distinct, Union, Intersect, ExceptDistinct, Union, Intersect, ExceptElementsElements First, FirstOrDefault, ElementAtFirst, FirstOrDefault, ElementAtAggregationAggregation Count, Sum, Min, Max, AverageCount, Sum, Min, Max, AverageConversionConversion ToArray, ToList, ToDictionaryToArray, ToList, ToDictionaryCastingCasting OfType<T>OfType<T>

Page 11: C# 3.0 & LINQ

DLinq For Relational Data

SqlConnection c = new SqlConnection(…);SqlConnection c = new SqlConnection(…);c.Open();c.Open();SqlCommand cmd = new SqlCommand(SqlCommand cmd = new SqlCommand( @"@"SELECT c.Name, c.PhoneSELECT c.Name, c.Phone FROM Customers cFROM Customers c WHERE c.City = @p0WHERE c.City = @p0");");cmd.Parameters.AddWithValue("cmd.Parameters.AddWithValue("@p0@p0", ", "London“);"London“);DataReader dr = c.Execute(cmd);DataReader dr = c.Execute(cmd);while (dr.Read()) {while (dr.Read()) { string name = dr.GetString(0);string name = dr.GetString(0); string phone = dr.GetString(1);string phone = dr.GetString(1); DateTime date = dr.GetDateTime(2);DateTime date = dr.GetDateTime(2);}}dr.Close();dr.Close();

Accessing data todayAccessing data todayQueries in Queries in

quotesquotes

Loosely bound Loosely bound argumentsarguments

Loosely typed Loosely typed result setsresult sets

No compile No compile time checkstime checks

Page 12: C# 3.0 & LINQ

public class Customer { … }public class Customer { … }

public class Northwind: DataContextpublic class Northwind: DataContext{{ public Table<Customer> Customers;public Table<Customer> Customers; … …}}

Northwind db = new Northwind(…);Northwind db = new Northwind(…);var contacts =var contacts = from c in db.Customersfrom c in db.Customers where c.City == "London"where c.City == "London" select new { c.Name, c.Phone };select new { c.Name, c.Phone };

DLinq For Relational DataAccessingAccessing data with DLinqdata with DLinq

Classes Classes describe datadescribe data

Strongly typed Strongly typed connectionconnection

Integrated Integrated query syntaxquery syntax

Strongly typed Strongly typed resultsresults

Tables are Tables are like collectionslike collections

Page 13: C# 3.0 & LINQ

DLinq For Relational Data

Language integrated data accessMaps tables and rows to classes and objectsBuilds on ADO.NET and .NET Transactions

MappingEncoded in attributesRelationships map to properties

PersistenceAutomatic change trackingUpdates through SQL or stored procedures

Page 14: C# 3.0 & LINQ

XLinq For XML Data

XmlDocument doc = new XmlDocument();XmlDocument doc = new XmlDocument();XmlElement contacts = doc.CreateElement("contacts");XmlElement contacts = doc.CreateElement("contacts");foreach (Customer c in customers)foreach (Customer c in customers) if (c.Country == "USA") {if (c.Country == "USA") { XmlElement e = doc.CreateElement("contact");XmlElement e = doc.CreateElement("contact"); XmlElement name = doc.CreateElement("name");XmlElement name = doc.CreateElement("name"); name.InnerText = c.CompanyName;name.InnerText = c.CompanyName; e.AppendChild(name);e.AppendChild(name); XmlElement phone = doc.CreateElement("phone");XmlElement phone = doc.CreateElement("phone"); phone.InnerText = c.Phone;phone.InnerText = c.Phone; e.AppendChild(phone);e.AppendChild(phone); contacts.AppendChild(e);contacts.AppendChild(e); }}doc.AppendChild(contacts);doc.AppendChild(contacts);

Programming XML todayProgramming XML today

<contacts> <contact> <name>Great Lakes Food</name> <phone>(503) 555-7123</phone> </contact> …</contacts>

Imperative Imperative modelmodel

Document Document centriccentric

No integrated No integrated queriesqueries

Memory Memory intensiveintensive

Page 15: C# 3.0 & LINQ

XLinq For XML Data

XElement contacts = new XElement("contacts",XElement contacts = new XElement("contacts", from c in customersfrom c in customers where c.Country == "USA"where c.Country == "USA" select new XElement("contact",select new XElement("contact", new XElement("name", c.CompanyName),new XElement("name", c.CompanyName), new XElement("phone", c.Phone)new XElement("phone", c.Phone) ))););

Programming XML with XLinqProgramming XML with XLinq Declarative Declarative modelmodel

ElementElementcentriccentric

Integrated Integrated queriesqueries

Smaller and Smaller and fasterfaster

Page 16: C# 3.0 & LINQ

XLinq For XML Data

Language integrated query for XMLExpressive power of XPath / XQueryBut with C# or VB as programming language

Leverages experience with DOMElement centric, not document centricFunctional constructionText nodes are just stringsSimplified XML namespace supportFaster and smaller

Page 17: C# 3.0 & LINQ

C# 3.0 Design Goals

• Integrate objects, relational, and XML

• Build on foundation laid in C# 1.0 and 2.0

• Run on the .NET 2.0 CLR

• Remain 100% backwards compatible

Page 18: C# 3.0 & LINQ

C# 3.0 Language Innovationsvar contacts =var contacts = from c in customersfrom c in customers where c.State == "WA"where c.State == "WA" select new { c.Name, c.Phone };select new { c.Name, c.Phone };

var contacts =var contacts = customerscustomers .Where(c => c.State == "WA").Where(c => c.State == "WA") .Select(c => new { c.Name, .Select(c => new { c.Name, c.Phone });c.Phone });Extension Extension

methodsmethods

Lambda Lambda expressionsexpressions

Query Query expressionsexpressions

Object Object initializersinitializers

Anonymous Anonymous typestypes

Local variable Local variable type inferencetype inference

Page 19: C# 3.0 & LINQ

Queries Through APIspublic class List<T>public class List<T>{{ public List<T> Where(Func<T, bool> predicate) { … }public List<T> Where(Func<T, bool> predicate) { … } public List<S> Select<S>(Func<T, S> selector) { … }public List<S> Select<S>(Func<T, S> selector) { … } … …}}

List<Customer> customers = GetCustomerList();List<Customer> customers = GetCustomerList();List<string> contacts =List<string> contacts = customers.Where(c => c.State == "WA").Select(c => customers.Where(c => c.State == "WA").Select(c => c.Name);c.Name);

Query operators Query operators are just methodsare just methods

But what about But what about other types?other types?Declare operators Declare operators

in all collections?in all collections?What about What about

arrays?arrays?

Methods compose Methods compose to form queriesto form queries

Page 20: C# 3.0 & LINQ

Queries Through APIspublic static class Sequencepublic static class Sequence{{ public static IEnumerable<T> Where<T>(IEnumerable<T> public static IEnumerable<T> Where<T>(IEnumerable<T> source,source, Func<T, bool> predicate) { … }Func<T, bool> predicate) { … }

public static IEnumerable<S> Select<T, S>(IEnumerable<T> public static IEnumerable<S> Select<T, S>(IEnumerable<T> source,source, Func<T, S> selector) { … }Func<T, S> selector) { … } … …}} Customer[] customers = GetCustomerArray();Customer[] customers = GetCustomerArray();

IEnumerable<string> contacts = Sequence.Select(IEnumerable<string> contacts = Sequence.Select( Sequence.Where(customers, c => c.State == Sequence.Where(customers, c => c.State == "WA"),"WA"), c => c.Name);c => c.Name);

Query operators Query operators are static methodsare static methods

Huh?Huh?

Want methods on Want methods on IEnumerable<T>IEnumerable<T>

Page 21: C# 3.0 & LINQ

namespace System.Querynamespace System.Query{{ public static class Sequencepublic static class Sequence {{ public static IEnumerable<T> Where<T>(this IEnumerable<T> public static IEnumerable<T> Where<T>(this IEnumerable<T> source,source, Func<T, bool> predicate) { … }Func<T, bool> predicate) { … }

public static IEnumerable<S> Select<T, S>(this public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source,IEnumerable<T> source, Func<T, S> selector) { … }Func<T, S> selector) { … } … … }}}}

Solution: Extension Methods

using System.Query;using System.Query;

ExtensionExtensionmethodsmethods

IEnumerable<string> contacts =IEnumerable<string> contacts = customers.Where(c => c.State == "WA").Select(c => customers.Where(c => c.State == "WA").Select(c => c.Name);c.Name);

Brings extensions Brings extensions into scopeinto scope

obj.Foo(x, y)obj.Foo(x, y)

XXX.Foo(obj, x, y)XXX.Foo(obj, x, y)

IntelliSense!IntelliSense!

Page 22: C# 3.0 & LINQ

Local Variable Type Inference

int i = 5;int i = 5;string s = "Hello";string s = "Hello";double d = 1.0;double d = 1.0;int[] numbers = new int[] {1, 2, 3};int[] numbers = new int[] {1, 2, 3};Dictionary<int,Order> orders = new Dictionary<int,Order> orders = new Dictionary<int,Order>();Dictionary<int,Order>();var i = 5;var i = 5;var s = "Hello";var s = "Hello";var d = 1.0;var d = 1.0;var numbers = new int[] {1, 2, 3};var numbers = new int[] {1, 2, 3};var orders = new Dictionary<int,Order>();var orders = new Dictionary<int,Order>();

““var” means same var” means same type as initializertype as initializer

Page 23: C# 3.0 & LINQ

Anonymous Typespublic class Customerpublic class Customer{{ public string Name;public string Name; public Address Address;public Address Address; public string Phone;public string Phone; public List<Order> Orders;public List<Order> Orders; … …}}

public class Contactpublic class Contact{{ public string Name;public string Name; public string Phone;public string Phone;}}

Customer c = GetCustomer(…);Customer c = GetCustomer(…);Contact x = new Contact { Name = c.Name, Phone = Contact x = new Contact { Name = c.Name, Phone = c.Phone };c.Phone };

Customer c = GetCustomer(…);Customer c = GetCustomer(…);var x = new { c.Name, c.Phone };var x = new { c.Name, c.Phone };

Customer c = GetCustomer(…);Customer c = GetCustomer(…);var x = new { Name = c.Name, Phone = c.Phone };var x = new { Name = c.Name, Phone = c.Phone };

class ???class ???{{ public string Name;public string Name; public string Phone;public string Phone;}}

Projection style Projection style initializerinitializer

Page 24: C# 3.0 & LINQ

var contacts =var contacts = from c in customersfrom c in customers where c.State == "WA"where c.State == "WA" select new { c.Name, c.Phone };select new { c.Name, c.Phone };

Anonymous Types

var contacts =var contacts = customers.customers. .Where(c => c.State == "WA“).Where(c => c.State == "WA“) .Select(c => new { c.Name, .Select(c => new { c.Name, c.Phone });c.Phone });

class ???class ???{{ public string Name;public string Name; public string Phone;public string Phone;}}

IEnumerable<???>IEnumerable<???>

foreach (var c in contacts) {foreach (var c in contacts) { Console.WriteLine(c.Name);Console.WriteLine(c.Name); Console.WriteLine(c.Phone);Console.WriteLine(c.Phone);}}

??????

Page 25: C# 3.0 & LINQ

public delegate bool Predicate<T>(T obj);public delegate bool Predicate<T>(T obj);

public class List<T>public class List<T>{{ public List<T> FindAll(Predicate<T> test) public List<T> FindAll(Predicate<T> test) { … }{ … } … …}}

Lambda Expressions

List<Customer> customers = List<Customer> customers = GetCustomerList();GetCustomerList();

List<Customer> x = customers.FindAll(List<Customer> x = customers.FindAll( delegate(Customer c) { return c.State == delegate(Customer c) { return c.State == "WA"; }"WA"; }););List<Customer> x = customers.FindAll(c => c.State List<Customer> x = customers.FindAll(c => c.State == "WA");== "WA");

ExplicitlyExplicitlytypedtyped

Statement Statement contextcontext

ImplicitlyImplicitlytypedtyped

Expression Expression contextcontext

Page 26: C# 3.0 & LINQ

Expression Treespublic class Northwind: DataContextpublic class Northwind: DataContext{{ public Table<Customer> public Table<Customer> Customers;Customers; public Table<Order> Orders;public Table<Order> Orders; … …}} Northwind db = new Northwind(…);Northwind db = new Northwind(…);

var query = from c in db.Customers where c.State == "WA" var query = from c in db.Customers where c.State == "WA" select c;select c;

Northwind db = new Northwind(…);Northwind db = new Northwind(…);var query = db.Customers.Where(c => c.State == var query = db.Customers.Where(c => c.State == "WA");"WA");

How does this How does this become SQL ?become SQL ?

public class Table<T>: IEnumerable<T>public class Table<T>: IEnumerable<T>{{ public Table<T> Where(Expression<Func<T, bool>> public Table<T> Where(Expression<Func<T, bool>> predicate);predicate); … …}}

Method asks for Method asks for expression treeexpression tree

System.Expressions.System.Expressions.Expression<T>Expression<T>

Page 27: C# 3.0 & LINQ

Expression TreesCode as Data

Func<Customer, bool> test = c => c.State == Func<Customer, bool> test = c => c.State == "WA";"WA";

Expression<Func<Customer, bool>> test = c => c.State Expression<Func<Customer, bool>> test = c => c.State == "WA";== "WA";ParameterExpression c =ParameterExpression c = Expression.Parameter(typeof(Customer), "c");Expression.Parameter(typeof(Customer), "c");Expression expr =Expression expr = Expression.EQ(Expression.EQ( Expression.Property(c, Expression.Property(c, typeof(Customer).GetProperty("State")),typeof(Customer).GetProperty("State")), Expression.Constant("WA")Expression.Constant("WA") ););Expression<Func<Customer, bool>> test =Expression<Func<Customer, bool>> test = Expression.Lambda<Func<Customer, bool>>(expr, c);Expression.Lambda<Func<Customer, bool>>(expr, c);

stringConstant :Constant

Value = "WA"

stateProperty :Property

PropertyName = "State"

equality :EQ

customerParam :ParameterExpression

Type = typeof(Customer)Name = c

test :Lambda

righttarget left

parameterexpression

Page 28: C# 3.0 & LINQ

Benefits Of LINQ

Unified querying of objects, relational, XML

Type checking and IntelliSense for queries

SQL and XQuery-like power in C# and VB

Extensibility model for languages / APIs

Page 29: C# 3.0 & LINQ

Call to Action

- Get VS 2005- Download LINQ preview

http://msdn.microsoft.com/netframework/future/linq/

Play Around & See the power!

Page 30: C# 3.0 & LINQ

Q & A