【问题标题】:LINQ: How do I select unique rows: max(id) with multiple columns?LINQ:如何选择唯一行:具有多列的 max(id)?
【发布时间】:2021-07-04 17:02:37
【问题描述】:

这是一个表的“玩具”示例,它有许多列和数千行。

我希望 FILTER OUT 任何包含相同 AcctNo、CustomerName 和 CustomerContact 的行,但保留 ONE 重复项的 ID(以便我以后可以访问记录) .

  • 例子:

    ID  AcctNo  CustomerName  CustomerContact
    1   1111    Acme Foods    John Smith
    2   1111    Acme Foods    John Smith
    3   1111    Acme Foods    Judy Lawson
    4   2222    YoyoDyne Inc  Thomas Pynchon
    5   2222    YoyoDyne Inc  Thomas Pynchon
    <= For AcctNo 1111, I want to save IDs 2 and 3
    
  • 小提琴: https://www.db-fiddle.com/f/bEECHi6XnvKAeXC4Xthrrr/1

  • 工作 SQL:

    select max(id) as ID,AcctNo,CustomerName,CustomerContact
    from test
    where AcctNo = '11111'
    group by AcctNo,CustomerName,CustomerContact
    

    OK:返回 ID 2 和 3:

    ID AcctNo CustomerName CustomerContact
    -- ------ ------------ ---------------
    2  11111  Acme Foods   John Smith
    3  11111  Acme Foods   Judy Lawson
    

问:此 SQL 的 LINQ 等效项是什么?

  • 尝试失败:

    IQueryable<CustomerData> query =
        from c in context.CustomerData
        where c.AcctNo == acctno
        group c by new { c.AcctNo , c.CustomerName, c.CustomerContact } into gcs
        select new { newID = gcs.Max(x => x.ID), gcs.AcctNo, gcs.CustomerName, gcs.CustomerContact }
    

【问题讨论】:

    标签: c# linq group-by


    【解决方案1】:

    你几乎猜对了。只需在投影中使用 Key 访问组属性。

    IQueryable<CustomerData> query =
        from c in context.CustomerData
        where c.AcctNo == acctno
        group c by new { c.AcctNo , c.CustomerName, c.CustomerContact } into gcs
        select new { newID = gcs.Max(x => x.ID), gcs.Key.AcctNo, gcs.Key.CustomerName, gcs.Key.CustomerContact }
    

    【讨论】:

      【解决方案2】:

      首先创建一个类似这样的自定义DTO视图模型

      public CustomerViewModel
      {
         public string AcctNo { get; set; }
         public string CustomerName { get; set; }
         public string CustomerContact { get; set; }
         public int MaxId { get; set; }
      }       
      

      查询

      context.CustomerData.Where(c => c.AcctNo == "1111")
             .GroupBy(c => new { c.AcctNo , c.CustomerName, c.CustomerContact })
             .Select(cg => new CustomerViewModel {
                            AcctNo  = cg.Key.AcctNo,
                            CustomerName  = cg.Key.CustomerName,
                            CustomerContact  = cg.Key.CustomerContact,
                            MaxId = cg.Max(c => c.ID)
              })
      

      【讨论】:

      • 1) 我缺少的部分是“c.Key.xxx”。 2)我想要在我的“真实”程序中做的是将一个结果传递给另一个 ASP.Net Core 页面。我正在考虑通过将行序列化为 JSON,然后使用 JSON 字符串调用新页面来做到这一点。您的“DTO”想法会简化这一点。谢谢你!
      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多