简体   繁体   English

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

[英]How to use Group By with Join and Min in Linq

I have two tables. 我有两张桌子。

Order: 订购:

  • ID ID
  • ProductID 产品编号
  • DeliveryDate 邮寄日期

Product: 产品:

  • ID ID
  • Name 名称
  • Description 描述

I want to get the list of all product with earliest delivery date. 我想获取最早交货日期的所有产品清单。

I am getting correct data by using following sql. 我通过使用以下sql获取正确的数据。 This gives me list of all products with earliest delivery date. 这给了我所有交货日期最早的产品清单。

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

I have tried to write it using Linq but something is missing. 我尝试使用Linq编写它,但是缺少某些内容。 I am not able to identify how can I write this query. 我无法确定如何编写此查询。

I have tried out relative stack overflow solutions but not helped in my case. 我已经尝试了相对的堆栈溢出解决方案,但在我的情况下没有帮助。

My Linq is : 我的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();

It gives me data after join and group by. 加入并分组后会给我数据。 Where should I put Min in the Linq to get the Earliest DeliveryDate for the Product? 我应该在哪里把Min放在Linq中,以获得该产品的最早交货日期?

I assume you have a navigation property Product.Orders . 我假设您具有导航属性Product.Orders If not, it's highly recommended to add it to your code. 如果没有,强烈建议将其添加到您的代码中。 Having that property, this will achieve what you want: 拥有该属性,就可以实现您想要的:

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

The cast to DateTime? 转换为DateTime? is to prevent exceptions when products don't have orders. 是为了防止产品没有订单时出现异常。

If for some reason you don't have the navigation property and really can't add it at the moment you can use: 如果由于某种原因您没有导航属性,并且现在确实无法添加它,则可以使用:

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)
}

Note that by starting the query at Product and not joining with Order you don't need the grouping any more. 请注意,通过在“ Product处开始查询而不加入“ Order您就不再需要分组了。

I used some classes to stand in for the database, but does this work? 我使用了一些类来代表数据库,但这行得通吗?

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);
     }
  }
}

The output is 输出是

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

If you're trying to order your groups you can use the "OrderBy" linq method. 如果您要订购组,可以使用“ OrderBy” linq方法。

Apply the following after the .GroupBy() 在.GroupBy()之后应用以下内容

.OrderBy(group => group.First().DeliveryDate).ToListAsync();

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

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