【问题标题】:linq group by two columns and get only rows with same group by valueslinq 按两列分组并仅获取具有相同分组值的行
【发布时间】:2021-07-08 09:21:32
【问题描述】:

我想使用 LINQ 按两列分组(Parent_IdName)检索数据,并仅获取具有相同分组值的行的结果。

Child
---------
Id        Parent_Id      Name
1         1              c1
2         1              c2
3         2              c1 <-----
4         2              c1 <-----
5         3              c2
6         3              c3
7         4              c4 <-----

如您所见,对于Parent_Id 12Name 是不同的。所以,我不知道那些行。
我想要的结果是这样的

Parent_Id   Name
2           c1 
4           c4

我试过的是

from c in Child
group c by new
    {
        c.Parent_Id,
        c.Name
    } into gcs
    select new Child_Model()
    {
        Parent_Id = gcs.Key.Parent_Id,
        Name= gcs.Key.Name
    };

但它返回所有行。

【问题讨论】:

  • 所以你想要那些NameParent_Id 组合至少出现两次的元素?还是您只想要该组合点击率最高的那些?
  • @lidqy,如果 NameParent_Id 在 group 之后相同,我会抓住这一行。
  • 您想要所有出现 2 次或多次相同 p-id+name 的人吗?还是只有一个 - 最多?我知道在你的例子中只有一个,但在现实生活中数据可能会改变......
  • @lidqy,我已经更新了我的问题。
  • 对于 Parent_Id 1 和 2,名称不同 -- 我猜你的意思是 Parent_Id 1 和 3?

标签: c# linq group-by


【解决方案1】:

正如您所描述的,您应该仅按Parent_id 分组,并获得具有不同Names 的组:

var result = children
    .GroupBy(c => c.Parent_Id)
    .Where(g => g.Select(t => t.Name).Distinct().Count() == 1)
    .Select(g => new
    {
        Parent_Id = g.Key,
        Name = g.Select(c => c.Name).First()
    });

【讨论】:

  • 我认为这是一个比在结果集上使用 Distinct 更好的解决方案,因为这样您可以选择在投影中包含 Id,如果出于某种原因需要这样做.
  • @JohnH,我想我已经向你展示了如何包含它。这仍然使用 Distinct()。
  • 我认为 JohnH 并不是说​​应该避免使用 Distinct。只是它在早期阶段使用过。这里的要点是分组不应包含Name
【解决方案2】:

根据 Gert Arnold 的要求进行最终编辑:

var result = from r in (from c in children
             where !children.Any(cc => cc.Id != c.Id &&
                cc.Parent_Id == c.Parent_Id &&
                cc.Name != c.Name)
             select new  {
                Parent_Id = c.Parent_Id,
                Name = c.Name
             }).Distinct().ToList()
             select new Child_Model
             {
                Parent_Id = r.Parent_Id,
                Name = r.Name
             };

【讨论】:

  • 抱歉,我已经编辑了我的问题,我们可以删除 c.Count() &gt;1 吗?你也可以用简单的 LINQ 查询给我看,而不是 lambda 表达式。
  • @StevenSann,哦,好吧,这很重要。我要编辑我的回复。
【解决方案3】:
var myModel = Child.GroupBy( c => $"{c.Parent_Id}|{c.Name}",
          (k, list) => new Child_Model{
              Parent_Id = list.First().Parent_Id,
              Name = list.First().Parent_Id,
              Count = list.Count()})
          .Max (cm => cm.Count);

【讨论】:

    【解决方案4】:

    您可以添加条件来过滤结果(groupName.Count() &gt; 1):

    from c in childs 
    group c by new { c.Parent_Id, c.Name } into gcs 
    where gcs.Count() > 1 
    select new { gcs.Key.Parent_Id, gcs.Key.Name }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多