linq - 过滤一个实体的子集合
问题描述
我有以下实体:
public class Product {
public Int32 ProductId { get; set; }
public Double Price { get; set; }
public virtual ProductType ProductType { get; set; }
}
public class ProductType {
public Int32 ProductTypeId { get; set; }
public virtual ICollection<ProductTypeLocalization> ProductTypeLocalizations { get; set; }
}
public class ProductTypeLocalization {
public Int32 ProductTypeId { get; set; }
public String Language { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public virtual ProductType { get; set; }
}
然后我有一个查询如下:
var models = await products.Select(product => new {
Id = product.Id,
Price = product.Price,
ProductType = new {
Id = product.ProductType.ProductTypeId,
Name = ???,
Description = ???
}
}).ToListAsync()
在我的查询中显示
Name = ???,
Description ???
我需要Name
与. Description
_ProductTypeLocalization
Language == "en"
我可以在每个上使用 FirstOrDefault 但我认为这不是一种有效的方法。
最好的方法是什么?
解决方案
LEFT OUTER JOIN
对于这种情况,翻译似乎是最好的。
理论上,EF Core 查询翻译器应该能够将常用FirstOrDefault()
表达式合并为单一表达式,LEFT OUTER JOIN
就像它对可选参考导航属性所做的那样。
在实践中(截至目前最新的 EF Core 2.2)它并没有这样做,而是为每个选定的字段生成单独的相关子查询。
假设每种产品类型都有针对特定语言的 0 或 1 个本地化,则可以通过以下方式实现所需的翻译SelectMany
:
var models = await products.SelectMany(
product => product.ProductType.ProductTypeLocalizations
.DefaultIfEmpty()
.Where(ptl => ptl == null || ptl.Language == "en"),
(product, ptl) => new
{
Id = product.ProductId,
Price = product.Price,
ProductType = new
{
Id = product.ProductType.ProductTypeId,
Name = ptl.Name,
Description = ptl.Description
}
})
.ToListAsync();
或使用 LINQ 查询语法的等效且可读性更好的版本:
var models = await (
from product in products
let pt = product.ProductType
from ptl in pt.ProductTypeLocalizations.DefaultIfEmpty()
where ptl == null || ptl.Language == "en"
select new
{
Id = product.ProductId,
Price = product.Price,
ProductType = new
{
Id = pt.ProductTypeId,
Name = ptl.Name,
Description = ptl.Description
}
}).ToListAsync();
推荐阅读
- python - 如何在 GitHub 上拉取请求后运行脚本?
- node.js - 从 cli 生成新的 Angular 应用程序引发 npm 错误
- nginx - Nginx 在子目录中分离应用程序
- c# - WPF 控件绑定并不总是更新 UI
- python-3.x - 无法导入“scrapy_splash”pylint(导入错误)
- apache-spark-sql - 如何在使用字典时使用 replace() 方法替换列值?
- python - 如何修复这个 NumPy loadtxt 函数?
- python - 将 docx 转换为 html 会引发 python MemoryError
- r - 使用 dplyr 根据分组变量计算列 NA
- machine-learning - 为什么 ALS 可以很容易地并行计算?