Microsoft Developer Network > Forums Home > Archived Forums Forums > LINQ Project General > Why does EntitySet no longer implement IQueryable?
Ask a questionAsk a question
 

AnswerWhy does EntitySet no longer implement IQueryable?

  • Monday, August 06, 2007 2:04 PMJoe AlbahariMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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 Smile) 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

  • Monday, August 06, 2007 5:06 PMJomo Fisher MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

     

    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

  • Monday, August 06, 2007 5:06 PMJomo Fisher MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

     

    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.

  • Tuesday, August 07, 2007 6:10 AMJoe AlbahariMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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.Customers
        select 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.Customers
        select 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.

  • Tuesday, August 07, 2007 6:42 AMJoe AlbahariMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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...
  • Sunday, January 18, 2009 4:14 PMjopincar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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

  • Monday, September 21, 2009 9:10 PMDynamic Linq Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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