New "Orcas" Language Feature: Lambda Expressions
page 6 of 8
by Scott Guthrie
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 29746/ 75

Lambda Expressions to Expression Trees

Compiling lambdas expressions to code delegates works great when we want to evaluate them against in-memory data like with our List collection above.  But consider cases where you want to query data from a database (the code below was written using the built-in LINQ to SQL object relational mapper in "Orcas"):

Listing 7

Here I am retrieving a sequence of strongly typed "Product" objects from a database, and I am expressing a filter to use via a Lambda expression to a Where() extension method. 

What I absolutely do not want to have happen is to retrieve all of the product rows from the database, surface them as objects within a local collection, and then run the same in-memory Where() extension method above to perform the filter.  This would be hugely inefficient and not scale to large databases.  Instead, I'd like the LINQ to SQL ORM to translate my Lambda filter above into a SQL expression, and perform the filter query in the remote SQL database.  That way I'd only return those rows that match the query (and have a very efficient database lookup). 

Framework developers can achieve this by declaring their Lambda expression arguments to be of type Expression<T> instead of Func<T>.  This will cause a Lambda expression argument to be compiled as an expression tree that we can then piece apart and analyze at runtime:

Listing 8

Note above how I took the same p=>p.LastName == "Guthrie" Lambda expression that we used earlier, but this time assigned it to an Expression<Func<Person, bool>> variable instead of a Func<Person,bool> datatype.  Rather then generate IL, the compiler will instead assign an expression tree object that I can then use as a framework developer to analyze the Lambda expression and evaluate it however I want (for example, I could pick out the types, names and values declared in the expression). 

In the case of LINQ to SQL, it can take this Lambda filter statement and translate it into standard relational SQL to execute against a database (logically a "SELECT * from Products where UnitPrice < 55").

<span lang=EN>IQueryable<T> Interface</span>

To help framework developers build query-enabled data providers, LINQ ships with the IQueryable<T> interface.  This implements the standard LINQ extension method query operators, and provides a more convenient way to implement the processing of a complex tree of expressions (for example: something like the below scenario where I'm using three different extension methods and two lambdas to retrieve 10 products from a database):

Listing 9

For some great blog post series that cover how to build custom LINQ enabled data providers using IQueryable<T>, please check out these great blog posts from others below:

LINQ to Amazon: Part 1, Part 2, Part 3

LINQ to NHibernate: Part 1, Part 2, Part 3

LINQ to LDAP: Part 0, Part 1, Part 2, Part 3, Part 4, Part 5


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-07-15 5:46:09 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search