Databases Reference
In-Depth Information
called,
“Join”
in this example. The
typeArguments
is an array of the type arguments that
will be used by the .NET runtime to create a specific implementation of the generic
Join
method. The
arguments
parameter is an array of
Expression
objects that represent the
arguments that will be passed to the method. With the selectors built earlier, here is how
the
Join
LINQ expression can be created in code:
MethodCallExpression
joinCall
= Expression.Call(
typeof(Queryable),
“Join”,
new Type[] {
typeof(Product),
typeof(Supplier),
typeof(int?),
typeof(Product)
},
new Expression[] {
productQuery.Expression,
supplierQuery.Expression,
productKeySelector
,
supplierKeySelector
,
resultSelector
}
)
NOTE
It is easy to confuse
typeArguments
with
arguments
. With the dozen or so different
overloads that the
Expression.Call
method defines, this results in compiler errors
that make very little sense and do not help to understand the problem. When working
with
MethodCallExpression
objects, remember that in a generic method call, the
typeArguments
are the things that go between
< >
, and
arguments
are the things that
go between
( )
.
The final step in constructing a LINQ query with expression objects is to convert the LINQ
expression to an
IQueryable
object and replace the original query. Here is how this can be
done in the example with products and suppliers:
IQueryProvider queryProvider = productQuery.Provider;
productQuery = queryProvider.CreateQuery(
joinCall
);
Here you use the
IQueryProvider
object returned by the
Provider
property of the original
product query. The
IQueryProvider
interface defines a
CreateQuery
method that takes a
lambda expression object as a parameter and returns an
IQueryable
object that represents
the new query. By passing a
MethodCallExpression
to the
CreateQuery
method of the
query provider, you create a new
IQueryable
(that is, a new LINQ query) that returns
results of a join between Product and Supplier queries.