Here’s an interesting problem that I hope someone can lend a hand with.
I have a DomainService class with the following query:
[Query]
public IEnumerable<BatchResult> GetBatchResults(int batchId)
{
return ObjectContext.BatchQueries
.Include("BatchTCResults")
.Include("BatchANFResults")
.Where(x => x.BatchId == batchId)
.Where(x => x.BatchTCResults.Any() || x.BatchANFResults.Any())
.ToArray() // enumerate because projection calls a method that EF will poop it's pants on
.Select(x => new BatchResult
{
BatchQueryId = x.Id,
Route = x.Routing,
Account = x.Account,
Amount = x.Amount,
CheckNumber = x.CheckNumber,
Severity = BatchResult.DetermineOverallSeverity(x)
});
}
This works BUT I really need the paging/sorting information passed from the Silverlight client to be applied before enumeration happens in the line calling .ToArray()
The client side is using the DomainDataSource Silverlight control.
How can I achieve this?
The easiest way is adding paging/sorting/filtering parameters to the method arguments list and adding corresponding LINQ query operators to your data context query in the service method. However, in this case you’ll loose client-side
IQueryablefeatures. I mean, client’s queries will reach only the application server, but won’t get to the database. And you’ll need some layer between theDomainContextand the UI:DomainDataSourceis not likely to work.Exposing the results of the query as
IQueryableusingAsQueryable()won’t help since expression trees will be unconditionally compiled into code in order to execute your LINQ-to-Objects operators.Somewhat harder option is using arguments as in first case together with writing your own
IQueryablewrapper over the client-side query object. This wrapper would extract parameters from query expressions and pass them to the service as method arguments. Well, I’d only try this if I had enough spare time.Another difficult way is doing analogous thing server-side. It’s possible to get an
IQueryableobject that has the expression tree passed from client in aDomainService. You’ll need to override theDomainService.Querymethod. Then you’ll be able to extract part of the query expression that relates to paging/sorting, save it to a field and then apply to the database query. However,Querymethod is single for all methods in a givenDomainService. Therefore, you’ll probably end with a big table method that decides what to do for each of the service query methods. Needless to say, the service will become very difficult.To conclude, I strongly recommend you the first option.