LINQ:如何选择唯一行:具有多列的 max(id)?

Posted

技术标签:

【中文标题】LINQ:如何选择唯一行:具有多列的 max(id)?【英文标题】:LINQ: How do I select unique rows: max(id) with multiple columns? 【发布时间】: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 

【问题讨论】:

【参考方案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”想法会简化这一点。谢谢你!

以上是关于LINQ:如何选择唯一行:具有多列的 max(id)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle SQL 中不使用 distinct 选择从多个 max(case when) 派生的唯一行

选择具有唯一 linq 查询的所有相关实体 [重复]

如何使用 Sequelize.JS 选择具有 2 个唯一列的所有行?

如何在没有分组依据的情况下选择具有最大技能属性的 ID

C# Linq 如何选择数据表中多列的不同行数

根据多列和日期时间删除重复项