Linq 筛选一个实体的子集合

Linq 筛选一个实体的子集合,linq,linq-to-entities,entity-framework-core,Linq,Linq To Entities,Entity Framework Core,我拥有以下实体: 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 virtua

我拥有以下实体:

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; }
}
在我的查询中,它显示在哪里

Name = ???,
Description ???
我需要使用
语言==“en”
ProductTypeLocalization
获取
Name
Description

我可以对每一个都使用FirstOrDefault,但我认为这不是一种有效的方法


最好的方法是什么

左外连接
翻译似乎最适合这种情况

理论上,EF Core查询转换器应该能够将通用的
FirstOrDefault()
表达式合并为单个
左外部联接
,就像它对可选参考导航属性所做的那样

在实践中(最新一次是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();

你是对的。我错过了恋爱。刚刚更新了我的代码。对不起,我想最好的办法是做一个小测验,但是哪一个呢?选择只能用于集合。您的
ProductType
将有
ProductTypeLocalization
列表,是否正确?查询中需要什么,那么它应该
ProductType
应该有单个
ProductTypeLocalization
是的,基本上我需要选择ProductType和一个productTypeLocation,其中语言匹配“en”。。。但我一直在尝试选择和选择很多,但现在运气好。你能提供代码来澄清你的意思吗?
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();