2016-01-29 5 views
1

У меня есть классы, такие как:Как фильтровать по полям свойства навигации в Entity Framework?

public class ProductInCategory 
{ 
    public Guid Guid { get; set; } 
    public long ProductID { get; set; } 
    public long ProductCategoryID { get; set; } 

    public virtual Product Product { get; set; } 
    public virtual ProductCategory ProductCategory { get; set; } 
} 

public class Product 
{ 
    public virtual ICollection<ProductInCategory> ProductsInCategories { get; set; } 

    // and other fields and navigation properties not important for this example 
} 

А теперь я хочу, чтобы выполнить запрос, который получает все продукты с использованием Entity Framework с жадной загрузкой с конкретным ProductCategoryID'S:

using (var db = new EntityDataModel()) 
{ 
    var node = db.Tree.FirstOrDefault(x => x.Guid == editedNode); 
    List<long> descentantIds = db.Tree 
           .Where(x => x.AncestorID == node.AncestorID) 
           .Select(x => x.DescendantID).ToList(); 

    List<Product> products = db.Products 
     .Include("Details") 
     .Include("Prices") 
     .Include("Prices.Currency") 
     .Include("Prices.Seller") 
     .Include("Translations") 
     .Include("Translations.Language") 
     .Include("ProductsInCategories") 
     .Where(x => ...)) // how to filter by ProductsInCategories.ProductCategoryID (which in my case is descentantIds) ? 
     .ToList(); 
} 

Я думаю, что я должен ввести Где положение что-то похожее на .Where(x => descentantIds.Contains(x.ProductsInCategories.ProductCategoryID)), но это не сработает.

Here похожее решение, но я не знаю, как его применять в моем случае.

Благодарим за любые советы!

+0

Что именно вы хотите? что descentantIds содержит ЛЮБОЙ из идентификаторов в ProductsInCategories? все? наоборот? – DevilSuichiro

+0

Я хочу получить эквивалент SQL 'WHERE ProductsInCategories.ProductCategoryID IN (1, 2, 3 .. n)', но я не вижу, как я могу получить значение выражения лямбда ProductCategoryID в моем навигационном свойстве ProductsInCategories. В моем случае, где указано: 'IQueryable ' –

+0

ProductionCategories - это ICollection of Products, который ProductCategoryID вам нужен? – DevilSuichiro

ответ

2

Попробуйте

.SelectMany(x => x.ProductsInCategories.Where(c => descentantIds.Contains(c.ProductCategoryID))).Select(c => c.Product).Distinct() 
+0

Это работает :) Спасибо @mariovalens;) –

0

Хотя @mariovalens дал рабочее решение, которое решить мою проблему, я нашел еще один. Я вставляю их обоих. Возможно, это будет полезно для других;)

Обратите внимание, что для правильной загрузочной загрузки вставьте методы .Include() после методов фильтрации, таких как SelectMany(), Select(), Where() и т. Д. Ввод .Include() до того, как эти методы будут возвращает значения null в свойствах навигации.

using (var db = new EntityDataModel()) 
{ 
    var node = db.Tree.FirstOrDefault(x => x.Guid == editedNode); 
    List<long> descentantIds = db.Tree 
       .Where(x => x.AncestorID == node.AncestorID) 
       .Select(x => x.DescendantID) 
       .ToList(); 

    List<Product> method1 = db.Products 
     .SelectMany(x => x.ProductsInCategories.Where(c => descentantIds.Contains(c.ProductCategoryID))).Select(c => c.Product).Distinct() 
     .Include(c => c.Assets.Select(c1 => c1.Translations.Select(c2 => c2.Language))) 
     .Include(c => c.Tags.Select(c1 => c1.Translations.Select(c2 => c2.Language))) 
     .Include(c => c.Details) 
     .Include(c => c.Prices.Select(c1 => c1.Currency)) 
     .Include(c => c.Prices.Select(c1 => c1.Seller)) 
     .Include(c => c.Translations.Select(c1 => c1.Language)) 
     .Include(c => c.ProductsInCategories) 
     .ToList(); 

    var method2 = (from product in db.Products 
       join productsInCategories in db.ProductsInCategories 
       on product.ID equals productsInCategories.ProductID 
       join productsCategories in db.ProductsCategories 
       on productsInCategories.ProductCategoryID equals productsCategories.ID 
       where descentantIds.Contains(productsInCategories.ProductCategoryID) 
       select product) 
       .Include(c => c.Assets.Select(c1 => c1.Translations.Select(c2 => c2.Language))) 
       .Include(c => c.Tags.Select(c1 => c1.Translations.Select(c2 => c2.Language))) 
       .Include(c => c.Details) 
       .Include(c => c.Prices.Select(c1 => c1.Currency)) 
       .Include(c => c.Prices.Select(c1 => c1.Seller)) 
       .Include(c => c.Translations.Select(c1 => c1.Language)) 
       .Include(c => c.ProductsInCategories); 

    var result = method2.ToList<Product>(); 
}