LINQ

C#
本文总阅读量:
  1. 1. 1 All LINQ queries must start with the ‘var’ keyword. In fact, the very purpose of the ‘var’ keyword is to start a LINQ query!
  2. 2. 2 All LINQ queries must use query syntax.
  3. 3. 3 To retrieve all customers from the customer table, you must perform a query similar to the following:
  4. 4. 4 A LINQ to SQL or EF query will be executed in one round-trip only if the query was built in a single step.
  5. 5. 5 Because SQL emits flat result sets, LINQ queries must be structured to emit flat result sets, too.

1 All LINQ queries must start with the ‘var’ keyword. In fact, the very purpose of the ‘var’ keyword is to start a LINQ query!

1
2
3
4
5
6
string[] people = new [] { "Tom", "Dick", "Harry" };
var filteredPeople = people.Where (p => p.Length > 3);
//is precisely equivalent to:

string[] people = new [] { "Tom", "Dick", "Harry" };
IEnumerable<string> filteredPeople = people.Where (p => p.Length > 3);

2 All LINQ queries must use query syntax.

  • lambda syntax

  • query syntax

    1
    2
    3
    4
    5
    6
    7
    8
    //Here's an example of lambda syntax:

    string[] people = new [] { "Tom", "Dick", "Harry" };
    var filteredPeople = people.Where (p => p.Length > 3);
    Here's the same thing expressed in query syntax:

    //string[] people = new [] { "Tom", "Dick", "Harry" };
    var filteredPeople = from p in people where p.Length > 3 select p;

3 To retrieve all customers from the customer table, you must perform a query similar to the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
The expression:

from c in db.Customers select c
is a frivolous query! You can simply go:

db.Customers
Similarly, the following LINQ to XML query:

var xe = from e in myXDocument.Descendants ("phone") select e;
can be simplified to:

var xe = myXDocument.Descendants ("phone");
And this:

Customer customer = (from c in db.Customers where c.ID == 123 select c)
.Single();
can be simplified to:

Customer customer = db.Customers.Single (c => c.ID == 123);

4 A LINQ to SQL or EF query will be executed in one round-trip only if the query was built in a single step.

LINQ follows a lazy evaluation model, which means queries execute not when constructed, but when enumerated. This means you can build up a query in as many steps as you like, and it won’t actually hit the server until you eventually start consuming the results.

For instance, the following query retrieves the names of all customers whose name starts with the letter ‘A’, and who have made at least two purchases. We build this query in three steps:

1
2
3
4
5
6
var query = db.Customers.Where (c => c.Name.StartsWith ("A"));
query = query.Where (c => c.Purchases.Count() >= 2);
var result = query.Select (c => c.Name);

foreach (string name in result) // Only now is the query executed!
Console.WriteLine (name);

5 Because SQL emits flat result sets, LINQ queries must be structured to emit flat result sets, too.

For example, if you want to retrieve the names of customers in the state of WA along with all their purchases, you can simply do the following:

1
2
3
4
5
6
7
from c in db.Customers
where c.State == "WA"
select new
{
c.Name,
c.Purchases // An EntitySet (collection)
}

The hierarchical result from this query is much easier to work with than a flat result set!

We can achieve the same result without association properties as follows:

1
2
3
4
5
6
7
from c in db.Customers
where c.State == "WA"
select new
{
c.Name,
Purchases = db.Purchases.Where (p => p.CustomerID == c.ID)
}