15.2 A First Look at LINQ Query Expressions 15.3 LINQ and Generic Collections. 15.4 LINQ and Nongeneric Collections[r]
Trang 1Chapter 15 Introduction
to LINQ
Trang 2“LINQ allows you to build strongly typed query expressions, which can be applied to a number of LINQ targets to manipulate “data” in the broadest sense of the word Here, you will learn about LINQ to Objects, which allows you to apply LINQ expressions to containers of data (arrays, collections, custom types) This information will serve you well when we examine how to apply LINQ expressions to relational databases (via LINQ to ADO) and XML documents.”
Trang 315.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators 15.6 Investigating the C# LINQ Query Operators
Trang 415.1 The Role of LINQ
symmetrical manner in which programmers can obtain and manipulate “data” in the broad sense of the term
Trang 5The Role of LINQ
Dynamically-created string queries
Doesn't provide compile-time checking
Trang 615.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators 15.6 Investigating the C# LINQ Query Operators
Trang 715.2 A First Look at LINQ Query
Expressions
Must include initializer
Can’t be null Why not?
What happens if “var” is a class in scope?
Works in for loops
Trang 8LINQ Query Expressions
and can’t subtype?
IEnumerable<T>, without deriving a new interface?
Solution: Extension methods aren’t really members of the target type, but the syntax makes them look that way
Compile-time type safety is preserved
Trang 9LINQ Query Expressions
Not for properties, events, operators
Currently under consideration
Equivalent to calling the static method
Difference from actually extending the class?
Implicitness
Trang 10LINQ Query Expressions
Define a Static Class
Define a static method whose first argument is an object of type T
[System.Runtime.CompilerServices.Extension] attribute on first parameter tells CLR the method is an Extension
C# binds the attribute to keyword “this”
Create a T object, and call the method as if it were a member of the object
it searches for an extension method in scope with matching
Trang 11Replacing LINQ Extension Methods
Extension Methods have lower priority of resolution than type
members
extension method, the type’s member will be called, and there is
no ambiguity
implementations of the Standard Query Operators
class MyList : IEnumerable < int > {
public IEnumerable < int > Where (
// LINQ queries on MyList objects will call this // instead of Sequence.Where()
}
Trang 12 Can have implicitly typed variables
NB: no statement bodies in preview compiler
Trang 13 Lambda expressions
Participate in type inference
If expression body, get expression trees
Lambda Expression
delegate R Func < A , R >( A arg );
Func < int , int > f1 = x => x + 1 ;
Func < int , double > f2 = x => x + 1 ;
Func < double , int > f3 = x => x + 1 ;
Trang 14Lambda Expression
If call Select(customers, c => c.Name);
T, S mapped to appropriate types
public static IEnumerable < S > Select < T , S >(
{
foreach ( T element in source )
}
Trang 15The Role of Differed Execution
until you iterate over their contents
same container and obtain the latest and greatest
results
Trang 16The Role of Immediate Execution
of foreach logic, you are able to call any number of
extension methods defined by the Enumerable type
ToDictionary<TSource,TKey>(), and ToList<T>()
container
Trang 1715.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators 15.6 Investigating the C# LINQ Query Operators
Trang 1815.3 LINQ and Generic Collections
members of the System.Collections.Generic namespace, such as the List<T> type
class Car
{
public string PetName = string Empty ;
public string Color = string Empty ;
public int Speed ;
public string Make = string Empty ; }
static void Main ( string [] args )
{
Trang 20Applying a LINQ Expression
property is greater than 55
static void GetFastCars ( List < Car > myCars )
{
// Create a query expression.
foreach ( var car in fastCars )
{
}
}
Trang 2115.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators 15.6 Investigating the C# LINQ Query Operators
Trang 2215.4 LINQ and Nongeneric Collections
nongeneric collections using the generic
Enumerable.OfType<T>() method
// Extract the ints from the ArrayList.
"string data" });
// Prints out 10, 400, and 8.
foreach ( int i in myInts )
{
Trang 23Console WriteLine ( "***** LINQ over ArrayList *****\n" );
// Here is a nongeneric collection of cars.
ArrayList myCars = new ArrayList () {
new Car { PetName = "Henry" , Color = "Silver" , Speed = 100 , Make
Trang 2415.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators
15.6 Investigating the C# LINQ Query Operators
Trang 2515.5 The Internal Representation of LINQ
Query Operators
using various C# query operators (such as from, in,
where, orderby, and select)
various methods of the System.Linq.Enumerable type
Func<>
Trang 26Query Expressions
Important for interaction with DB
Built-in data structures
Leave query planning to data structure designer
Trang 27Query Expressions
As with collections:
not an interface
necessary for backwards compatibility
syntax
Trang 28Building Query Expressions with Query Operators
(from, in, where, orderby, etc.) is the most common and most straightforward approach
static void QueryStringWithOperators ()
{
string [] currentVideoGames = { "Morrowind" , "BioShock" ,
"Half Life 2: Episode 1" , "The Darkness" ,
"Daxter" , "System Shock 2" };
// Build a query expression using query operators.
// Print out the results.
Trang 29Building Query Expressions Using the Enumerable Type and Lambdas
Enumerable type directly is much more verbose than making use of the C# query operators
static void QueryStringsWithEnumerableAndLambdas ()
{
string [] currentVideoGames = { "Morrowind" , "BioShock" ,
"Half Life 2: Episode 1" , "The Darkness" ,
"Daxter" , "System Shock 2" };
// Build a query expression using extension methods
// granted to the Array via the Enumerable type.
// Print out the results.
foreach ( var game in subset )
}
Trang 30Building Query Expressions Using the
Enumerable Type and Anonymous Methods
static void QueryStringsWithAnonymousMethods ()
{
string [] currentVideoGames = { "Morrowind" , "BioShock" ,
"Half Life 2: Episode 1" , "The Darkness" ,
"Daxter" , "System Shock 2" };
// Build the necessary Func<> delegates using anonymous methods.
Func < string , bool > searchFilter =
delegate ( string game ) { return game Length > 6 ; };
Func < string , string > itemToProcess = delegate ( string s ) {
return s ; };
// Pass the delegates into the methods of Enumerable.
// Print out the results.
Trang 31Building Query Expressions Using the Enumerable Type and Raw Delegates
class VeryComplexQueryExpression
{
public static void QueryStringsWithRawDelegates ()
{
Console WriteLine ( "***** Using Raw Delegates *****" );
string [] currentVideoGames = { "Morrowind" , "BioShock" ,
"Half Life 2: Episode 1" , "The Darkness" ,
"Daxter" , "System Shock 2" };
// Build the necessary Func<> delegates using anonymous methods.
Func < string , bool > searchFilter = new Func < string , bool >( Filter );
Func < string , string > itemToProcess = new
Func < string , string >( ProcessItem );
// Pass the delegates into the methods of Enumerable.
var subset = currentVideoGames
Where ( searchFilter ) OrderBy ( itemToProcess ) Select ( itemToProcess );
// Print out the results.
foreach ( var game in subset )
Console WriteLine ( "Item: {0}" , game );
Trang 32 Many methods of Enumerable require delegates (Func<> in particular) as parameters
Under C# 2008, any method requiring a delegate parameter can instead be passed a lambda expression
Lambda expressions are simply anonymous methods in
disguise (which greatly improve readability)
Trang 3315.1 Understanding the Role of LINQ
15.2 A First Look at LINQ Query Expressions
15.3 LINQ and Generic Collections
15.4 LINQ and Nongeneric Collections
15.5 The Internal Representation of LINQ Query Operators
15.6 Investigating the C# LINQ Query Operators
Trang 3415.6 Investigating the C# LINQ Query
where Used to define a restriction for which items to extract
from a container select Used to select a sequence from the container
join, on, equals, into
Performs joins based on specified key Remember, these “joins” do not need to have anything to do with data in a relational database.
orderby, ascending, Allows the resulting subset to be ordered in ascending
Trang 35Building a New Test Project
FunWithLinqExpressions
your Main() method
Trang 36class Car
{
public string PetName = string Empty ;
public string Color = string Empty ;
public int Speed ;
public string Make = string Empty ;
public override string ToString () {
return string Format ( "Make={0}, Color={1}, Speed={2}, PetName={3}" ,
Make , Color , Speed , PetName );
} }
static void Main ( string [] args )
{
Console WriteLine ( "***** Fun with Query Expressions *****\n" );
// This array will be the basis of our testing
Car [] myCars = new [] {
new Car { PetName = "Henry" , Color = "Silver" , Speed = 100 , Make = "BMW" },
new Car { PetName = "Daisy" , Color = "Tan" , Speed = 90 , Make = "BMW" },
new Car { PetName = "Mary" , Color = "Black" , Speed = 55 , Make = "VW" },
new Car { PetName = "Clunker" , Color = "Rust" , Speed = 5 , Make = "Yugo" },
new Car { PetName = "Hank" , Color = "Tan" , Speed = 0 , Make = "Ford" },
new Car { PetName = "Sven" , Color = "White" , Speed = 90 , Make = "Ford" },
new Car { PetName = "Mary" , Color = "Black" , Speed = 55 , Make = "VW" },
new Car { PetName = "Zippy" , Color = "Yellow" , Speed = 55 , Make = "VW" },
new Car { PetName = "Melvin" , Color = "White" , Speed = 43 , Make = "Ford" }
};
// We will call various methods here!
Example 15.1 Investigating the C# LINQ Query Operators
Trang 37Basic Selection Syntax
static void BasicSelection ( Car [] myCars ) {
// Get everything.
Console WriteLine ( "All cars:" );
var allCars = from c in myCars select c ;
foreach ( var c in allCars ) {
Console WriteLine ( c ToString ());
} }
Trang 38Obtaining Subsets of Data
where operator
expression select item;
static void GetSubsets ( Car [] myCars ) {
// Now get only the BMWs.
var onlyBMWs = from c in myCars where c Make ==
"BMW" select c ;
CHAPTER 14 n 466 AN INTRODUCTION TO LINQ foreach ( Car c in onlyBMWs )
Trang 39Projecting New Data Types
read-only backing field for each specified name
var makesColors = from c in myCars select new { c Make ,
c Color };
foreach ( var o in makesColors ) {
// Could also use Make and Color properties directly.
Console WriteLine ( o ToString ());
}
Trang 40Reversing Result Sets
Enumerable type
static void ReversedSelection ( Car [] myCars ) {
// Get everything in reverse.
Console WriteLine ( "All cars in reverse:" );
var subset = ( from c in myCars select
Trang 41Sorting Expressions
A query expression can take an orderby operator to sort items in the subset by a
specific value
To view the results in a descending order, simply include the descending operator
var result = from item in container orderby value ascending/descending select item;
Trang 421 static void OrderedResults(Car[] myCars)
3 // Order all the cars by PetName.
4 var subset = from c in myCars orderby c.PetName select c;
5 Console.WriteLine( "Ordered by PetName:" );
6 foreach (Car c in subset)
8 Console.WriteLine(c.ToString());
10 // Now find the cars that are going less than 55 mph,
11 // and order by descending PetName
12 subset = from c in myCars
13 where c.Speed > 55 orderby c.PetName descending select c;
14 Console.WriteLine( "\nCars going faster than 55, ordered by PetName:" );
15 foreach (Car c in subset)
17 Console.WriteLine(c.ToString());
Trang 43Finding Differences
obtaining a result set that determines the differences between
two IEnumerable<T> compatible containers
static void GetDiff()
var carDiff =(from c in myCars select c)
.Except(from c2 in yourCars select c2);
Console.WriteLine( "Here is what you don't have, but I do:" );
foreach ( string s in carDiff)
Console.WriteLine(s); // Prints Yugo.
}
Trang 44provide a single, symmetrical manner to interact with
diverse forms of data
sets, it is common to make use of the var keyword to
represent the underlying data type
making calls on static members of the
System.Linq.Enumerable type
Trang 45References