【问题标题】:Linq select array items based on sub class propertyLinq 根据子类属性选择数组项
【发布时间】:2021-04-29 15:23:41
【问题描述】:

我有一个看起来像这样的课程

public class ProductCategory {
  public int ProductCategoryId { get; set; }
  public string ProductCategoryName { get; set; }
  public List<Product> Products { get; set; }

产品有一些属性,例如名称、价格等。

我想要一个 linq 查询,它将返回带有产品数组的产品类别的这种结构,但仅在产品的属性等于值的情况下。例如价格是 10。

我试过了

productCategory.SelectMany(p => p.Products).Where(x => x.Price == 10)

但这会返回一系列产品,但我想要包含所有符合条件的产品的产品类别。

作为一个额外的挑战,我也有多个标准,所以在这个例子中说价格等于 10、30 或 50。有一个标准有两个值,这增加了复杂性。我打算通过调用不同的选择标准然后在最后连接它们来做到这一点

var equalToTen = productCategory.Select... x.Price == 10
var equalToThirty = productCategory.Select... x.Price == 30
var equalToFiftyANdNameIsTest = productCategory.Select... x.Price == 50 && x.Name == "Test"

return equalToTen.Union(equalToThirty).Union(equalToFiftyANdNameIsTest)

但我确信它可以在单个语句中完成,而无需在末尾连接。

更新

ProductCaegory 也不是一个单一的。它是对数据库进行 EF 查询的结果。所以它需要返回子类 Product 查询匹配的多个 ProductCategories。

【问题讨论】:

  • 这里的问题是您希望ProductCategorys 作为查询的结果,但在其Products 属性中包含元素子集。这意味着您要么必须操作现有的 ProductCategory 对象,要么创建新对象。
  • @Dominik 确实如此,而且由于 LINQ 查询不应该有副作用,我们不应该操纵原件

标签: c# linq


【解决方案1】:

所以您想要价格在某个列表中的产品类别,并且只有这些价格?

var prices = new[]{10,30};
categories.Select(c => new ProductCategory {
  ProductCategoryId = c.ProductCategoryId,
  ProductCategoryName = c.ProductCategoryName,
  Products = c.Products.Where(p => prices.Any(pp => pp == p.Price) || (p.Price == 50 && p.Name == "Test")).ToList()
}).Where(p => p.Products.Count > 0);

这会将类别投影到具有过滤产品的新猫。只有具有相关价格(10 or 30) (or 50 and called test) 的产品才能晋级.. 然后只有仍然有产品的类别被退回

标准线可以表示为

Products = c.Products.Where(p => p.Price == 10 || p.Price == 30 || (p.Price == 50 && p.Name == "Test")).ToList()

这可能更容易阅读;我最初在数组中有 3 个项目,但我将保留数组形式作为 LINQ 中典型 WHERE price IN (10,30,50) 的演示 - 我们从另一个角度接近它并询问“这些价格为 10、30、50是它们中的任何一个等于 p.Price" 而不是 "is p.Price in [10,30,50]"。其他形式的简化也是可能的,例如.Where(p =&gt; prices.Contains(p.Price) ...,但我倾向于回退到 Any 路线,因为它允许更复杂的构造

【讨论】:

  • 这看起来不错。我的问题是原始 ProductCategory 和 Products 是映射到表的实体,所以我收到一个错误:“无法在 LINQ to Entities 查询中构造实体或复杂类型 'ProductOption'。”
  • 如果什么是 ProductOption?在任何情况下,只需从 new 之后删除 ProductCategory (或选项:您是否出于问题的目的编辑了您的类名?)以投影到匿名类型。它在大多数情况下仍然可以正常工作,如果您真的需要它作为 ProductCategory,您可以稍后将其映射回来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
相关资源
最近更新 更多