What is "it" in Entity Framework
Forgive me if this has been asked before but "it" doesn't come up in any of my searches. I have two database tables Person and Employee modeling a Table-per-Type (e.g. Employee is-a Person). In my edmx designer I have defined a single entity Employee that maps each column to their respective underlying table (e.g. Name -> Person, Salary -> Employee).
"it" allows me to do stuff like this in a LINQ expression:
context.Employees.Where("it.Name LIKE 'M%' AND it.Salary > 1234")
Are there any good links explaining how I can expect "it" to behave? I presume it's not a generic LINQ thing and that it is somewhat specific to Entity Framework.
EDIT 0: The generated C# code for the ObjectContext follows:
public partial class TestObjectContext : ObjectContext
{
// lo开发者_如何学Cts of boilerplate removed for clarity
public ObjectSet<Employee> Employees
{
get
{
if ((_Employees == null))
{
_Employees = base.CreateObjectSet<Employee>("Employees");
}
return _Employees;
}
}
}
it
is the default alias for the current ObjectQuery
command. Please refer to the documentation for Query Builder methods, especially the Alias section:
Query builder methods are applied sequentially to construct a cumulative query command. This means that the current ObjectQuery command is treated like a sub-query to which the current method is applied.
In a query builder method, you refer to the current ObjectQuery command by using an alias. By default, the string "it" is the alias that represents the current command, as in the following example:
int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
context.Products
.Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));
When you set the Name property of an ObjectQuery, that value become the alias in subsequent methods. The following example extends the previous one by setting name of the ObjectQuery to "product" and then using this alias in the subsequent OrderBy method:
// Set the Name property for the query and then
// use that name as the alias in the subsequent
// OrderBy method.
productQuery.Name = "product";
ObjectQuery<Product> filteredProduct = productQuery.OrderBy("product.ProductID");
You are talking about the Dynamic LINQ
library.
If you have VS 2008 installed you can find a detailed API document at
<path to vs2008>\Samples\1033\CSharpSamples\LinqSamples\DynamicQuery\Dynamic Expressions.html
Or download from here
Here's the Scott Gu's article on Dynamic LINQ
Here's an extract from Dynamic Expressions.html
file.
Current Instance
When parsing a lambda expression with a single unnamed parameter, the members of the unnamed parameter are automatically in scope in the expression string, and the current instance given by the unnamed parameter can be referenced in whole using the keyword it. For example,
customers.Where("Country = @0", country);
is equivalent to
customers.Where("it.Country = @0", country);
The IQueryable extension methods all parse their expression arguments as lambda expressions with a single unnamed parameter.
Dynamic Lambda Invocation
An expression can reference other dynamic lambda expressions through dynamic lambda invocations. A dynamic lambda invocation consists of a substitution variable identifier that references an instance of System.Linq.Expressions.LambdaExpression, followed by an argument list. The arguments supplied must be compatible with the parameter list of the given dynamic lambda expression.
The following parses two separate dynamic lambda expressions and then combines them in a predicate expression through dynamic lambda invocations:
Expression<Func<Customer, bool>> e1 =
DynamicExpression.ParseLambda<Customer, bool>("City = \"London\"");
Expression<Func<Customer, bool>> e2 =
DynamicExpression.ParseLambda<Customer, bool>("Orders.Count >= 10");
IQueryable<Customer> query =
db.Customers.Where("@0(it) and @1(it)", e1, e2);
It is of course possible to combine static and dynamic lambda expressions in this fashion:
Expression<Func<Customer, bool>> e1 =
c => c.City == "London";
Expression<Func<Customer, bool>> e2 =
DynamicExpression.ParseLambda<Customer, bool>("Orders.Count >= 10");
IQueryable<Customer> query =
db.Customers.Where("@0(it) and @1(it)", e1, e2);
The examples above both have the same effect as:
IQueryable<Customer> query =
db.Customers.Where(c => c.City == "London" && c.Orders.Count >= 10);
精彩评论