1

感谢您的关注!

背景

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

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

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

var ProductTypesToShow = [1, 3, 5];

因此,对于每个返回的客户,我只想显示他们购买的类型为13或的产品5如果客户从未购买过至少一种类型为 、 或 的产品13则应5从结果集中删除整个客户对象。

我试过的

我试过使用这样的东西:

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

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

  1. 仅选择购买类型为 、 或 的产品13客户5

  2. 在这些客户中,删除任何不属于 、 或 类型的产品13然后5再将数据发送回视图。

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

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

4

3 回答 3

2

很难说它是否适用于 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.

于 2013-04-09T16:01:31.083 回答
2

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

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;
于 2013-04-09T16:09:41.677 回答
0
var results = customers
.Where(cust=>cust.ProductsPurchased.Any(ProductsToShow.Contains))
.Select(cust=>new{
           cust.Name,
           Purchases=cust.ProductsPurchased.Where(ProductsToShow.Contains)
    });
于 2013-04-09T16:09:13.117 回答