EF急切地加载已筛选的子对象/仅筛选子对象
本文关键字:筛选 对象 加载 EF | 更新日期: 2023-09-27 18:30:13
我的EF Poco类结构如下,我试图实现的是获得所有类别产品,包括产品和ProductName,但只有语言ID为1 的ProductNames
我不想过滤根对象。我不需要加载所有产品名称,只需要加载语言ID为1 的产品名称
我不知道如何做到这一点。例如,我尝试在下面查询
var products = db.CategoryProduct.Include("Product.ProductName").
Where(p=>p.Product.ProductName.Any(a=>a.LanguageId==1)).ToList();
但此项筛选所有具有语言ID为1的ProductName的类别产品。这不是我想要的,因为所有产品都有5种不同语言的名称。我只是不想为每个产品急切地加载5次,但对于语言ID=1 只有1次
public partial class CategoryProduct
{
[Key]
public int ProductId { get; set; }
public virtual Product Product { get; set; }
}
public partial class Product
{
public virtual ICollection<ProductName> ProductName { get; set; }
}
public partial class ProductName
{
public int ProductId { get; set; }
public int LanguageId { get; set; }
public string Name { get; set; }
public virtual Product Product { get; set; }
}
恐怕使用热切加载无法过滤相关实体,除非您将查询投影为匿名类型或DTO:
var products = db.CategoryProduct.Include(c=>c.Product.ProductName)
.Select(c=> new CategoryProductDTO()
{
//...
ProductNames= c.Product.ProductName.Where(a=>a.LanguageId==1)
})
.ToList();
如果你不想投影你的查询,并且你想加载特定的相关实体,那么我建议你使用显式加载:
var catproduct = db.CategoryProduct.Include(c=>c.Product).FirstOrDefault();// This is just an example, select the category product that you need to load the related entities
context.Entry(catproduct.Product)
.Collection(b => b.ProductName)
.Query()
.Where(pn => pn.LanguageId==1)
.Load();
但是IMHO第一个变体是
这并不容易实现,但以下内容可能会实现:
from cp in db.CategoryProduct.Include(x => x.Product)
from pn in cp.Product.ProductName.Where(x => x.LanguageId == 1).DefaultIfEmpty()
select new {
Cat = cp,
Name1 = pn.Name
}
那么您的产品在Cat.product中,名称在Name1中。
其基本思想是在ProductName
上设置一个LEFT JOIN
。