首页 > 解决方案 > 查询产品中的独占使用实体

问题描述

我有 3 个要加入的列表:Products、AcceptedOffers 和Deliverys

List<Product> products = new List<Product>() {
    new Product(){ Id = 1, Name = "Drink" }
};

List<AcceptedOffer> accepted = new List<AcceptedOffer>() {
    new AcceptedOffer(){ Id = 10, ProductId = 1  },
    new AcceptedOffer(){ Id = 11, ProductId = 1  }
};

List<Delivery> deliveries = new List<Delivery>() {
    new Delivery(){ Id = 101, ProductId = 1, Status = "Success" },
    new Delivery(){ Id = 102, ProductId = 1, Status = "Failure"}
};

我想将交货与接受的报价联系起来,但我找不到一种方法来查询专门使用每个 AcceptedOffer/Delivery:

var test = from d in deliveries
           join p in products on d.ProductId equals p.Id
           join ao in accepted on p.Id equals ao.ProductId
           select new { d, p, ao };

这给出了:

Drink | 10 | Success
Drink | 11 | Success
Drink | 10 | Failure
Drink | 11 | Failure

如果我按 Accepted Offer 分组,那么FirstOrDefault()两次交付都成功;Group by Delivery 和第一个 AcceptedOffer 是一样的..

我需要:

Drink | 10 | Success
Drink | 11 | Failure

什么是数学/查询巫术让我独家使用每一面?

标签: c#linqmath

解决方案


从技术上讲,您可以尝试使用Linq SelectManyZip为了实现zipping(即,将商品NN交付一起加入):

Accepted Offer            ->  Delivery
----------------------------------------------------------------------------
{ Id = 10, ProductId = 1} -> { Id = 101, ProductId = 1, Status = "Success" } 
{ Id = 11, ProductId = 1} -> { Id = 102, ProductId = 1, Status = "Failure" }
 ...
 N-th offer               -> N-th delivery

代码:

   var result = products // for each product                              
     .SelectMany(prod => deliveries             
         // we get corresponding deliveries
        .Where(del => del.ProductId = prod.Id)  
         // which we mechanically zip with filtered accepted offeres
        .Zip(accepted.Where(acc => acc.ProductId = prod.Id), 
           (del, acc) => new {
             d  = del.Status,
             p  = prod.Id,   
             ao = acc.Id,
         }));

推荐阅读