我的EF Poco类结构如下所示,我尝试实现的是获取所有CategoryProducts包括Products和ProductName,但只有ProductNames具有languageid = 1
我不想过滤Root对象。我不需要加载所有产品名称,只需加载带有languageid = 1
的productname我不知道如何实现这一目标。例如,我尝试了下面的查询
var products = db.CategoryProduct.Include("Product.ProductName").
Where(p=>p.Product.ProductName.Any(a=>a.LanguageId==1)).ToList();
但是这个过滤了所有具有带有languageid = 1的ProductName的categoryProducts。这不是我想要的,因为所有产品都有5种不同语言的名称。我只是不想急切地为每个产品加载5次,但只有1次加载languageid = 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; }
}
答案 0 :(得分:1)
这不容易实现,但以下内容可能会这样做:
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中的名字。
基本想法是在LEFT JOIN
上设置ProductName
。
答案 1 :(得分:1)
我担心使用急切加载您无法过滤相关实体,除非您以匿名类型或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();
但恕我直言,第一个变种是要走的路