Database Reference
In-Depth Information
Following is the output of the code in Listing 11-4:
Using eSQL for the query...
Customer: Jill Robinson Invoice for: New Tires, Amount: 302.99
Using LINQ for the query...
Customer: Jill Robinson, Invoice for: New Tires, Amount: 302.99
How It Works
From the definition of our GetInvoices() function in Listing 11-3, we see that it takes a collection of Invoices and
returns a collection of Invoices. On the CLR side, this translates to taking an IQueryable<Invoice> and returning an
IQueryable<Invoice> .
In the eSQL expression, we use the GetInvoices() function in the from clause. We pass in the unfiltered
collection of Invoices and our GetInvoices() function returns the filtered collection. We further filter the
collection by date and the customer's city using a where clause. Then we use CreateQuery<Invoice>() to build
the ObjectQuery<Invoice> . In building the query, we pass in the parameter to filter by city and use the Include()
method to include the related customers. Once we have the ObjectQuery<Invoice> , we iterate over the resulting
collection and print out the invoices that matched the two filters that we applied.
For the LINQ query, the story is a little more interesting. Here we build the expression using the GetInvoices()
method in the from clause and filter the resulting collection by date and city, much like we did with the
eSQLexpression. However, to use our function in a LINQ query, we need to implement a CLR method that takes
an IQueryable<Invoice > and returns an IQueryable<Invoice> . Unlike the stub method in Recipe 11-1, in which
the model-defined function returned a scalar value, here we have to provide an implementation in the body of the
method. Creating this method is often referred to as bootstrapping .
Here are some rules for bootstrapping:
IQueryable<T> .
Bootstrapping is required when a model-defined function returns an
IQueryable<T> but does not take an IQueryable<T> , the
bootstrapping method must be implemented in a partial class of the ObjectContext.
The second rule comes about because we can't return an IQueryable<T> that has meaning in our ObjectContext
without starting with an IQueryable<T> . If we pass in an IQueryable<T> , then we can perform some operation in
our bootstrapping method that returns a related IQueryable<T> . However, we can't manufacture an IQueryable<T>
outside of a partial class of our ObjectContext. In our example, we received an IQueryable<T> as a parameter, so we
are free to implement the bootstrapping code outside of a partial class of our ObjectContext.
In the implementation of our bootstrapping method, we get an instance of IQueryProvider from the
IQueryable<Invoice> through the Provider property. IQueryProvider.CreateQuery<Invoice>() allows us to tack
onto the expression tree for the IQueryable<T> . Here we add in the call to the GetInvoices() function, passing in the
collection of invoices that we have.
When a function returns an
11-3. Returning a Computed Column from a Model-Defined
Function
Problem
You want to return a computed column from a model-defined function.
 
Search WWH ::




Custom Search