如何在实体框架中按导航属性中的字段进行筛选
本文关键字:字段 筛选 属性 实体 框架 导航 | 更新日期: 2023-09-27 18:32:36
我有这样的类:
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
}
现在我想执行查询,该查询使用实体框架获取所有产品,并预先加载特定的产品类别 ID:
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))
的 Where 子句,但这不起作用。
这是类似的解决方案,但我不知道如何在我的情况下应用它。
谢谢你的任何建议!
试试这个
.SelectMany(x => x.ProductsInCategories.Where(c => descentantIds.Contains(c.ProductCategoryID))).Select(c => c.Product).Distinct()
虽然@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>();
}