Problem with subquery in projection

Posts   
 
    
kvarley
User
Posts: 16
Joined: 06-Jun-2008
# Posted on: 26-Jun-2008 21:30:19   

Hello,

I am having trouble with something that we are trying to do with doing a subquery within a projection into our own domain classes. Essentially, we can acheive what we are trying to do just fine if we are only dealing with the IQueryable with the projection on its own. However, If we use the IQueryable in question within another query expression we are getting an ORMQueryConstructionException with the message:

Couldn't create any correlation filter lambda because the nested query didn't have any correlation filters. Please specify a filter in the nested query to tie the nested query to the parent query

I have a full test solution that I can attach, one that I sent to Frans regarding another issue that Frans fixed prior to the RTM release. However, since I 'm not sure if we are attempting to do something that is simply unsupported, here's the relevant code. If you'd prefer the entire solution and database backup, please let me know.

We have a class with the following linq query:


 public IQueryable<Product> GetProductsWithPrefetch()
        {
            var metaData = new LinqMetaData(DataAccessContext.Current);
            return from p in metaData.Product.WithPath(path => path.Prefetch(p => p.CategoryCollectionViaProductCategoryMap))
                   select new Product
                              {
                                  Id = p.Id,
                                  UrlId = p.UrlId,
                                  Name = p.Name,
                                  Description = p.Description,
                                  Categories = (from cats in p.CategoryCollectionViaProductCategoryMap
                                                select new Category
                                                           {
                                                               Id = cats.Id,
                                                               UrlId = cats.UrlId,
                                                               Name = cats.Name,
                                                               Description = cats.Description
                                                           }).ToList()
                              };
        }

If I simply loop over the IQueryable returned from this method directly, as in the test below, I have no problems:



        public void GetProductsWithCategories_PrefetchWithMethod()
        {
            var metaData = new LinqMetaData(DataAccessContext.Current);

            foreach(var prod in _repository.GetProductsWithPrefetch())
            {
                if(prod.Categories != null && prod.Categories.Count > 0)
                {
                    Assert.Greater(prod.Categories.Count(),0);
                }
            }

        }


However, if I try to use the resulting IQueryable in a query expression, I get the correclated subquery exception.


 public void GetProductsWithCategories_PrefetchWithQueryExpression()
        {
            var metaData = new LinqMetaData(DataAccessContext.Current);

            var products = from p in _repository.GetProductsWithPrefetch()
                           select p;
            foreach (var prod in products)
            {
                if (prod.Categories != null && prod.Categories.Count > 0)
                {
                    Assert.Greater(prod.Categories.Count(), 0);
                }
            }

        }

I have also tried the same strategy without using prefetches and using an explicit subquery to populate the Categories collection with the same result.

I guess the point of what we are trying to do is so that we do not have to specify the projections into our domain objects in every query. Is what we are trying to do feasible?

Thanks in advance for any help.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 27-Jun-2008 10:33:17   

A nested query in a projection means that it has to execute a separate query and merge the data on the client. However, your wrapping query wraps the tree inside another query, which means that the projection with the nested query isn't really the top most projection and the query handler gets confused: the nested query really can't be made mergable with the projection it has to deal with now, as the projection is something else than the nested query is part of.

So this can't be done.

I also dont see the necessity for the WithPath, as you refer to the collection again in the nested query which is used to pull the data, so the WithPath is ignored anyway.

Frans Bouma | Lead developer LLBLGen Pro