Entity Framework 4.1 - Select

2019-07-22 05:07发布

问题:

I am using the following expressions:

ProductRepository.Query.Include(Function(x) x.ChildProducts.Select(Function(y) y.PriceTiers.Where(Function(z) z.IsActive))).Where(Function(x) x.Categories.Any(Function(y) y.ID = ID))

And getting this error:

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.

If I remove this:

.Where(Function(z) z.IsActive)

It works fine, but I need to filter the inactive price tiers.

Any ideas?

Update

Here is my solution:

Public Function GetProductsByCategoryID(ID As Integer) As System.Collections.Generic.IEnumerable(Of Core.Entities.Product) Implements Core.Interfaces.IProductService.GetProductsByCategoryID
        Dim Col = ProductRepository.Query.Where(Function(x) x.Display AndAlso x.Categories.Any(Function(y) y.ID = ID)) _
                  .Select(Function(x) New With { _
                              .Product = x,
                              .ChildProducts = x.ChildProducts.Where(Function(y) y.Display).Select(Function(y) New With { _
                                                                                                       .ChildProduct = y,
                                                                                                       .PriceTiers = y.PriceTiers.Where(Function(z) z.IsActive)
                                                                                                   })
                          }).ToList.Select(Function(x) x.Product)

        Return Col

    End Function

回答1:

You can't do that in single query without projection or separate query to load the navigation property. Lambda expression for Include accepts only dotted notation for references and Select for collections but you can't do any filtering.

Filtering is possible on in separate query when using DbContext API:

var data = context.Entry(product)
                  .Collection(p => p.ChildProducts)
                  .Query()
                  // Here are your filters
                  .Load();

Edit:

Projection requires something like:

var data = context.Products
                  .Where(...)
                  .Select(p => new 
                      {
                          Product = p,
                          ChildProducts = p.ChildProducts.Where(...)
                      });