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
Web
Databound
Application
grid
<book>
<title/>
<author/>
<year/>
<price/>
</book>
Xml
Transform
Order
Processing Read
Msg
WS
Xml R/W
XML Config
Order Mgt
WS
BR Check
Customer Mgt
Service
(HTTP + XML)
ORM
The LINQ Project
C# 3.0
VB 9.0
Others…
.NET Language Integrated Query
Standard
Query
Operators
DLinq
(ADO.NET)
XLinq
(System.Xml)
<book>
<title/>
<author/>
<year/>
<price/>
</book>
Objects
SQL
WinFS
XML
Service based Solution with LINQ
Web
Databound
O-LINQ
Application
grid
<book>
<title/>
<author/>
<year/>
<price/>
</book>
Xml
XLINQ
Transform
Order
Processing Read
O-LINQ
Msg
WS
Xml
XLINQ
R/W
XML Config
Order Mgt
WS
BR
O-LINQ
Check
Customer Mgt
Service
(HTTP + XML)
DLINQ
ORM
LINQ Style programming
class Contact { … };
List<Contact> contacts = new List<Contacts>();
foreach(Customer c in customers)
{
if(c.State == “WA”)
{
Contact ct = new Contact();
ct.Name = c.Name;
ct.Phone = c.Phone;
contacts.Add(ct);
}
}
var contacts =
from c in customers
where c.State == "WA"
select new { c.Name, c.Phone };
Query Expressions
Language integrated query syntax
from id in source
{ from id in source | where condition }
[ orderby ordering, ordering, … ]
select expr | group expr by key
[ into id query ]
Standard Query Operators
Restriction
Where
Projection
Select, SelectMany
Ordering
OrderBy, ThenBy
Grouping
GroupBy
Quantifiers
Any, All
Partitioning
Take, Skip, TakeWhile, SkipWhile
Sets
Distinct, Union, Intersect, Except
Elements
First, FirstOrDefault, ElementAt
Aggregation
Count, Sum, Min, Max, Average
Conversion
ToArray, ToList, ToDictionary
Casting
OfType<T>
DLinq For Relational Data
Accessing data today
Queries in
SqlConnection c = new SqlConnection(…);
quotes
c.Open();
SqlCommand cmd = new SqlCommand(
@"SELECT c.Name, c.Phone
Loosely bound
FROM Customers c
arguments
WHERE c.City = @p0");
cmd.Parameters.AddWithValue("@p0", "London“);
DataReader dr = c.Execute(cmd);
while (dr.Read()) {
Loosely typed
string name = dr.GetString(0);
result sets
string phone = dr.GetString(1);
DateTime date = dr.GetDateTime(2);
No compile
}
time checks
dr.Close();
DLinq For Relational Data
Accessing data with DLinq
public class Customer { … }
public class Northwind: DataContext
{
public Table<Customer> Customers;
…
}
Northwind db = new Northwind(…);
var contacts =
from c in db.Customers
where c.City == "London"
select new { c.Name, c.Phone };
Classes
describe data
Tables are
like collections
Strongly typed
connection
Integrated
query syntax
Strongly typed
results
DLinq For Relational Data
Language integrated data access
Maps tables and rows to classes and objects
Builds on ADO.NET and .NET Transactions
Mapping
Encoded in attributes
Relationships map to properties
Persistence
Automatic change tracking
Updates through SQL or stored procedures
XLinq For XML Data
Imperative
model
Programming XML today
XmlDocument doc = new XmlDocument();
XmlElement contacts = doc.CreateElement("contacts");
Document
foreach (Customer c in customers)
centric
if (c.Country == "USA") {
XmlElement e = doc.CreateElement("contact");
No integrated
XmlElement name = doc.CreateElement("name");
name.InnerText = c.CompanyName;
queries
e.AppendChild(name);
XmlElement phone = doc.CreateElement("phone");
Memory
phone.InnerText = c.Phone;
intensive
e.AppendChild(phone);
<contacts>
<contact>
contacts.AppendChild(e);
<name>Great Lakes Food</name>
}
<phone>(503) 555-7123</phone>
</contact>
doc.AppendChild(contacts);
…
</contacts>
XLinq For XML Data
Programming XML with XLinq
XElement contacts = new XElement("contacts",
from c in customers
where c.Country == "USA"
select new XElement("contact",
new XElement("name", c.CompanyName),
new XElement("phone", c.Phone)
)
);
Declarative
model
Element
centric
Integrated
queries
Smaller and
faster
XLinq For XML Data
Language integrated query for XML
Expressive power of XPath / XQuery
But with C# or VB as programming language
Leverages experience with DOM
Element centric, not document centric
Functional construction
Text nodes are just strings
Simplified XML namespace support
Faster and smaller
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
C# 3.0 Language Innovations
Query
var contacts =
expressions
from c in customers
where c.State == "WA"
Local variable
select new { c.Name, c.Phone };
type inference
Lambda
expressions
var contacts =
customers
.Where(c => c.State == "WA")
.Select(c => new { c.Name, c.Phone });
Extension
methods
Anonymous
types
Object
initializers
Queries Through APIs
Query operators
are just methods
public class List<T>
{
public List<T> Where(Func<T, bool> predicate) { … }
public List<S> Select<S>(Func<T, S> selector) { … }
…
}
Methods compose
to form queries
List<Customer> customers = GetCustomerList();
List<string> contacts =
customers.Where(c => c.State == "WA").Select(c => c.Name);
But what about
other types? Declare operators
in all collections?
What about
arrays?
Queries Through APIs
Query operators
are static methods
public static class Sequence
{
public static IEnumerable<T> Where<T>(IEnumerable<T> source,
Func<T, bool> predicate) { … }
public static IEnumerable<S> Select<T, S>(IEnumerable<T> source,
Func<T, S> selector) { … }
…
}
Huh?
Customer[] customers = GetCustomerArray();
IEnumerable<string> contacts = Sequence.Select(
Sequence.Where(customers, c => c.State == "WA"),
c => c.Name);
Want methods on
IEnumerable<T>
Solution: Extension Methods
namespace System.Query
Extension
{
methods
public static class Sequence
{
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, bool> predicate) { … }
public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source,
Func<T, S> selector) { … }
…
}
}
using System.Query;
Brings extensions
into scope
obj.Foo(x, y)

XXX.Foo(obj, x, y)
IEnumerable<string> contacts =
customers.Where(c => c.State == "WA").Select(c => c.Name);
IntelliSense!
Local Variable Type Inference
int i = 5;
string s = "Hello";
double d = 1.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new Dictionary<int,Order>();
var i = 5;
var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();
“var” means same
type as initializer
Anonymous Types
public class Customer
{
public string Name;
public Address Address;
public string Phone;
public List<Order> Orders;
…
}
public class Contact
{
public string Name;
public class
string ???
Phone;
{
}
public string Name;
public string Phone;
Customer c = GetCustomer(…);
}
Contact x = new Contact { Name = c.Name, Phone = c.Phone };
Customer c = GetCustomer(…);
var x = new { Name = c.Name, Phone = c.Phone };
Customer c = GetCustomer(…);
var x = new { c.Name, c.Phone };
Projection style
initializer
Anonymous Types
var contacts =
from c in customers
where c.State == "WA"
select new { c.Name, c.Phone };
IEnumerable<???>
???
class ???
{
public string Name;
public string Phone;
}
var contacts =
customers.
.Where(c => c.State == "WA“)
.Select(c => new { c.Name, c.Phone });
foreach (var c in contacts) {
Console.WriteLine(c.Name);
Console.WriteLine(c.Phone);
}
Lambda Expressions
public delegate bool Predicate<T>(T obj);
public class List<T>
{
public List<T> FindAll(Predicate<T> test) { … }
Statement
…
context
} Explicitly
typed
List<Customer>
customers = GetCustomerList();
List<Customer> x = customers.FindAll(
delegate(Customer c) { return c.State == "WA"; }
);
Implicitly
typed
Expression
context
List<Customer> x = customers.FindAll(c => c.State == "WA");
Expression Trees
public class Northwind: DataContext
{
public Table<Customer> Customers;
public Table<Order> Orders;
…
}
How does this
become SQL ?
Northwind db = new Northwind(…);
var query = from c in db.Customers where c.State == "WA" select c;
Northwind db = new Northwind(…);
var query = db.Customers.Where(c => c.State == "WA");
Method asks for
expression tree
public class Table<T>: IEnumerable<T>
{
public Table<T> Where(Expression<Func<T, bool>> predicate);
…
}
System.Expressions.
Expression<T>
Expression Trees
Code as Data
Func<Customer, bool> test = c => c.State == "WA";
Expression<Func<Customer, bool>> test = c => c.State == "WA";
ParameterExpression c = test :Lambda
Expression.Parameter(typeof(Customer), "c");
Expression expr =
parameter
expression
Expression.EQ(
Expression.Property(c,
customerParam :
ParameterExpression
typeof(Customer).GetProperty("State")),
equality :EQ
Type = typeof(Customer)
Expression.Constant("WA")
Name = c
);
target
left
right
Expression<Func<Customer, bool>> test =
Expression.Lambda<Func<Customer, bool>>(expr, c);
stateProperty :Property
PropertyName = "State"
stringConstant :
Constant
Value = "WA"
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
Call to Action
- Get VS 2005
- Download LINQ preview
http://msdn.microsoft.com/netframework/future/linq/
Play Around & See the power!
Q&A
Descargar

C# 3.0 & LINQ – Slides