Академический Документы
Профессиональный Документы
Культура Документы
If you're not a LINQ addict, you might wonder what the fuss is
about. SQL isn't broken, so why fix it? Why do we need another
querying language?
The popular answer is that LINQ is INtegrated with C# (or VB),
thereby eliminating the impedance mismatch between
programming languages and databases. While that's true, it's only
part of the story. More importantly, LINQ is, in general, a
significantly more productive querying language than SQL.
Compared to SQL, LINQ is simpler, tidier, and higher-level. It's rather
like comparing C# to C++. Sure, there are times when it's still best
to use C++ (as is the case with SQL), but in most situations,
working in a modern tidy language and not having to worry about
lower-level details is a big win.
SQL is a very old language—invented in 1974. Since then it's been
extended endlessly, but never redesigned. This has made the
language messy—rather like VB6 or Visual FoxPro. You might have
become so accustomed to this that you can't see anything wrong!
Let's take an example. You want to write a simple query that
retrieves customers as follows:
SELECT UPPER(Name)
FROM Customer
ORDER BY Name
That doesn't look too bad, right? But now suppose these results are
feeding a web page, and we want to retrieve just rows 21-30.
Suddenly, you need a subquery:
FROM Customer c1
WHERE
FROM Customer c2
ORDER BY c2.Name
ORDER BY c1.Name
Not only is this complicated and messy, but it violates the DRY
principle (Don't Repeat Yourself). Here's same query in LINQ. The
gain in simplicity is clear:
var query =
from c in db.Customers
orderby c.Name
select c.Name.ToUpper();
Composability
You might have noticed another more subtle (but important) benefit
of the LINQ approach. We chose to compose the query in two steps
—and this allows us to generalize the second step into a reusable
method as follows:
{
return query.Skip(skip).Take(take);
The important thing, here, is that we can apply our Paginate method
to any query. In other words, with LINQ you can break down a query
into parts, and then re-use some of those parts across your
application.
Associations
Another benefit of LINQ is that you can query across relationships
without having to join. For instance, suppose we want to list all
purchases made by customers who live in Washington, whose
purchased items exceed $1000 in total value. This requires joining
across 4 tables (Purchase, Customer, Address and PurchaseItem). In
LINQ, the query is effortless:
from p in db.Purchases
select p
from p in db.Purchases
select new
p.Description,
p.Customer.SalesPerson.Name,
PurchaseItemCount = p.PurchaseItems.Count()
Shaping Data
In SQL, queries come back as flat result sets. Quite often, though,
it's far more useful to work with hierarchical data. For example,
suppose we want to retrieve a selection of customers, each with
their high-value purchases. In LINQ, you can simply do this:
from c in db.Customers
select new
c.Name,
where HighValuePurchases.Any()
select new
c.Name,
HighValuePurchases
LINQ also supports flat outer joins, adhoc joins, subqueries, and
numerous other kinds of queries through a rich set of operators.
Parameterization
What if we wanted to parameterize our previous example, so that
the state "WA" came from a variable? This is all we do:
var query =
from c in db.Customers
...
Client Processing
LINQ lets you effortlessly shift part of the query onto the client for
processing. Why would you want to do this? With a heavily
burdened database server, it can actually sometimes improve
performance. As long as you don't take more data than you need (in
other words, you still do all the filtering on the server) you can often
help performance by shifting some of the burden of reordering,
transforming and regrouping the results onto a less loaded
application server. With LINQ, all you need to do is to slip
AsEnumerable() into the query, and everything from that point on
executes locally.