繁体   English   中英

如何使用LINQ根据子和比较器之间相交的值过滤和操作结果?

[英]How do I use LINQ to filter AND manipulate results based on values intersecting between a child and comparer?

谢谢你的期待!

背景

我在C#中编写并使用LINQ查询实体以获取报告。 在本报告中,我有一组基本上如下所示的实体:

Customer{
       Name: "Bob",
       ProductsPurchased: ArrayOfChildEntities[{
             ProductId: 1,
             ProductTypeId: 5,
             ProductName: "FooBuzz"
          },
          {...},
          {...}]
}

ProductsPurchased是包含产品类型ID的子实体数组。 假设我传入了一个类型id数组,用户从视图中的过滤器列表中选择了这些类型:

var ProductTypesToShow = [1, 3, 5];

因此,对于每一个客户回来了,我想只显示他们购买的是类型的产品135 如果客户从来购买类型中的至少一个产品13 ,或5 ,则该整个客户对象应该被从结果集中除去。

我试过了什么

我试过用这样的东西:

var customers = db.Customers.Where(c => c.ProductsPurchased.Select(p => ProductTypesToShow.Contains(p.ProductTypeId));

但这失败了。 我也尝试了各种版本的IntersectAny但遗憾的是它们都因某种原因而失败,或者它们无法完成我需要的所有事情:

  1. 只选择谁购买那种产品的客户135

  2. 这些客户的,除去任何产品不类型13 ,或5发送数据返回给视图之前。

最后,我写了一个foreach monstrosity,迭代在初始查询中找到的所有客户,然后迭代他们的产品按产品类型过滤,但这是慢得令人无法接受的(每个查询约3分钟!!)。

我觉得我必须在这里遗漏一些明显的东西。 任何建议表示赞赏!

很难说它是否适用于LINQ to Entities,但我会尝试一下:

var results = (from c in customers
               select new 
                   {
                       Name = c.Name,
                       Products = c.ProductsPurchased.Where(p => ProductTypesToShow.Contains(p.ProductTypeId))
                   } into c2
               where c2.Products.Any()
               select new
                   {
                       Name = c2.Name,
                       Products = c2.Products.ToArray()
                   }).ToArray();

它应该返回一个具有2个属性的匿名类型数组: NameProducts

这就是我在LinqToSql中的做法。 我不确定LinqToEntities是否支持Contains。

List<int> ProductTypesToShow = new List<int>() {1,3,5};

IQueryable<Product> productQuery = dc.Products
  .Where(p => ProductTypesToShow.Contains(p.ProductTypeId));  //deferred

var customerProductQuery =
  from c in dc.Customers
  join p in productQuery on c.CustomerID equals p.CustomerID into g //groupjoin!
  where g.Any()
  select new {Customer = c, Products = g.ToList()}; //customers with their products. deferred

List<Customer> result = new List<Customer>();

foreach(var pair in customerProductQuery)  //query executed
{  //manual result shaping
  Customer resultItem = pair.Customer;
  resultItem.Products = pair.Products;
  result.Add(resultItem);
}

return result;
var results = customers
.Where(cust=>cust.ProductsPurchased.Any(ProductsToShow.Contains))
.Select(cust=>new{
           cust.Name,
           Purchases=cust.ProductsPurchased.Where(ProductsToShow.Contains)
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM