Why does EntitySet no longer implement IQueryable?
- I notice EntitySet still doesn't implement IQueryable in Orcas Beta 2.
EntitySet implemented IQueryable in the May 2006 CTP - but not since. Will IQueryable support resurface for RTM? (Please say yes
) And if not, why?
Lack of IQueryable support cripples EntitySet's flexibility by making it impossible to leverage dynamically constructed expressions.
We're currently trying to port a (large and successful) system written in the May CTP to Beta 2, but are snookered by EntitySet's lack of IQueryable support. We've found that the strategic use of dynamically built expressions is essential in a real-world LINQ to SQL application to achieve reasonable code re-use (otherwise you end up with dozens of almost-identical queries.)
Dynamically building expressions might sound like hard work and maybe the LINQ team is trying to steer us away from this, but we (and others) have discovered that with a small set of extension methods it can be achieved effortlessly and with full type-safety to the consumer. No other approach can offer both.
Joe
Answers
Joe,
I agree dynamically constructed expressions are very important to a large class of LINQ to SQL applications. IQueryable on EntitySets won't be back for RTM but there are several new techniques available that may help you:
- Compiled queries can also be used for query reuse.
- The file Dynamic.cs in the samples shows how to dynamically create a query.
- You can use Expression factory classes and touch of reflection to solve almost any dynamic expression problem.
The design reason for not making EntitySet IQueryable is because there's not a clean way to reconcile Add\Remove on EntitySet with IQueryable's filtering and transformation ability. It seems clear that Added or Removed entities should affect the query results, but then we'd be trying to mix remoted SQL execution with local in-memory entities and there's just no clean way to do this in a complete way.
I believe one of the above techniques should help most any problem you have creating a dynamic expression. Please let us know if you find this to not be the case.
All Replies
Joe,
I agree dynamically constructed expressions are very important to a large class of LINQ to SQL applications. IQueryable on EntitySets won't be back for RTM but there are several new techniques available that may help you:
- Compiled queries can also be used for query reuse.
- The file Dynamic.cs in the samples shows how to dynamically create a query.
- You can use Expression factory classes and touch of reflection to solve almost any dynamic expression problem.
The design reason for not making EntitySet IQueryable is because there's not a clean way to reconcile Add\Remove on EntitySet with IQueryable's filtering and transformation ability. It seems clear that Added or Removed entities should affect the query results, but then we'd be trying to mix remoted SQL execution with local in-memory entities and there's just no clean way to do this in a complete way.
I believe one of the above techniques should help most any problem you have creating a dynamic expression. Please let us know if you find this to not be the case.
- Hi Jomo
Thanks for your reply. Regarding your suggestions:
- Exactly the same issue arises with compiled queries.
- The dynamic query sample means loss of static type safety. Further, we cannot use it in commerical applications because (a) the source is not public domain, and (b) it is unsupported by Microsoft, correct?
I'm puzzled as to how you'd go about using expression factory classes and reflection given that EntitySet doesn't implement IQueryable, so expects delegate-type arguments.
For instance, how would you get the following method to work?
void MyQuery ( type? orderPredicate)
{var query =from c in dataContext.Customersselect new{c.CompanyName,
TotalOrderCount = c.Orders.Count,SelectedOrders = c.Orders.Where (orderPredicate)};If you define orderPredicate of type Expression<Func<Orders,bool>> then the query doesn't compile....}
If you define orderPredicate of type Func<Orders,bool> then the query compiles but throws an exception when run.
Is, perhaps, the recommended workaround to do this:
var query =from c in dataContext.Customersselect new{c.CompanyName,
TotalOrderCount = c.Orders.Count,SelectedOrders =
dataContext.Orders
.Where (o => o.Customer == c).Where (orderPredicate)};
Unfortunately, this cannot be tested because of a separate issue. - P.S. Another reason not to use the dynamic query sample with EntitySets is that you can't - its Where method accepts IQueryable not IEnumerable...
I know this may not solve Joe's problem in general, but I wanted to get a solution that worked for me out there in case anyone else with my situation ends up on this thread after searching (like I did.)
I my case, I was storing a Func<D, bool> (where D is a linq to sql table type) that I was using either to query a Table or an EntitySet. What I found was that this was extremely slow for the Table case. I then changed what I stored to Expression<Func<D, bool>>. This made the Table case work at expected speeds. However, I could not longer use that object for the EntitySet case. The solution turned out to be quite simple for my scenario -- I just used the Compile method of Expression which conveniently returned a Func<D, bool> that I could then use for the EntitySet case.
Regards,
John Opincar
- Hi all,
Does anyone know the work around having a dynamic expression against an EntitySet? I tried something called LinqKit but it does NOT work with dynamically created expressions.
Thanks

