如何在Linq中使用Group By with Join和Min

时间:2017-12-13 14:16:28

标签: c# linq join group-by entity-framework-6

我有两张桌子。

订单:

  • ID
  • 的ProductID
  • DeliveryDate

产品:

  • ID
  • 名称
  • 描述

我想获得最早交货日期的所有产品清单。

我使用以下sql获取正确的数据。 这为我提供了最早交货日期的所有产品清单。

SELECT 
    p.Name, p.Description, min(o.DeliveryDate)
FROM Product p
JOIN Order o
On o.ProductID = p.ID
Group By p.ID;

我曾尝试使用Linq编写它,但缺少某些东西。 我无法确定如何编写此查询。

我已尝试过相对堆栈溢出解决方案但在我的情况下没有帮助。

我的Linq是:

await (from p in dbContext.Product
  join o in dbContext.Order
  on o.ProductID equals p.ID
  select new
  {
      p.ID,
      p.Name,
      p.Description,
      o.DeliveryDate
  }).GroupBy(g => g.ID).ToListAsync();

它在加入和分组后给我数据。我应该把Min放在Linq中以获得产品的最早交货日期?

3 个答案:

答案 0 :(得分:1)

我假设你有一个导航属性Product.Orders。如果没有,强烈建议将其添加到您的代码中。拥有该属性,这将实现您想要的:

from p in dbContext.Product
select new
{
    p.ID,
    p.Name,
    p.Description,
    MinDeliveryDate = (DateTime?)o.Orders.Min(o => o.DeliveryDate)
}

DateTime?的演员阵容是为了防止产品没有订单时出现例外情况。

如果由于某种原因您没有导航属性, 无法在您可以使用的时刻添加

from p in dbContext.Product
select new
{
    p.ID,
    p.Name,
    p.Description,
    MinDeliveryDate = (DateTime?)dbContext.Order
                                          .Where(o => o.ProductID == p.ID)
                                          .Min(o => o.DeliveryDate)
}

请注意,通过Product开始查询而不加入Order,您不再需要分组。

答案 1 :(得分:1)

我使用了一些类来代替数据库,但这有用吗?

class Product
{
  public int ID;
  public string Name;
  public string Description;
}

class Order
{
  public int ProductID;
  public DateTime DeliveryDate;
}

class Program
{
  static void Main(string[] args)
  {
     Product[] proTestData = new Product[]
     {
        new Product() {ID=1, Name="Widget", Description="Banded bulbous snarfblat"},
        new Product() {ID=2, Name="Gadget", Description="Hitchhiker's guide to the galaxy"}
     };
     Order[] ordTestData = new Order[]
     {
        new Order() {ProductID=1, DeliveryDate=new DateTime(2017,12,14)},
        new Order() {ProductID=1, DeliveryDate=new DateTime(2017,12,20)},
        new Order() {ProductID=2, DeliveryDate=new DateTime(2017,12,23)},
        new Order() {ProductID=2, DeliveryDate=new DateTime(2017,12,22)},
        new Order() {ProductID=2, DeliveryDate=new DateTime(2017,12,21)},
        new Order() {ProductID=1, DeliveryDate=new DateTime(2017,12,18)}
     };

     var rows =
        (from p in proTestData
         join o in ordTestData
         on p.ID equals o.ProductID
         group o.DeliveryDate by p into grp
         select new {
            grp.Key.ID,
            grp.Key.Name,
            grp.Key.Description,
            minDate = grp.Min()}
        ).ToList();

     foreach (var row in rows)
     {
        Console.WriteLine("{0}: {1}", row.Name, row.minDate);
     }
  }
}

输出

Widget: 12/14/2017 12:00:00 AM
Gadget: 12/21/2017 12:00:00 AM

答案 2 :(得分:0)

如果您尝试订购论坛,可以使用" OrderBy" linq方法。

在.GroupBy()

之后应用以下内容
.OrderBy(group => group.First().DeliveryDate).ToListAsync();