【问题标题】:How to write linq query with list of two joined tables a and B, then grouped by id of a, and with amount of joined rows from B如何使用两个连接表 a 和 B 的列表编写 linq 查询,然后按 a 的 id 分组,以及 B 中的连接行数
【发布时间】:2018-05-30 16:21:07
【问题描述】:

如何使用两个连接表 A 和 B 的列表编写 Linq 查询,然后按 A 的 id 分组,以及 B 中的连接行数

例如

class A{
   int Id,
   int BId,
   string AName
};

class B{
   int Id,
   string description
};

并显示如下(A 与 B 连接后)A.Bid = B.Id

A Id |  count(Id) | AName

坦率地说,我必须实现从 PHP 到 LINQ 的以下查询。所有依赖项都写在下面的查询中:

select("asset.id as Id,asset.AssetBundleID as AssetBundleID,asset.GUID as GUID,asset.Name as Id,asset.Name as Id,asset.DisplayName作为 DisplayName,asset.Description 作为 Description,asset.Category 作为 Category,asset.TexturesSize 作为 TexturesSize,asset.TexturesFileSize 作为 TexturesFileSize,asset.OthersSize 作为 OthersSize,asset.id 作为 Id,asset.OthersFileSize 作为 OthersFileSize,count(*) 作为实例数")
->来自(“资产”)
->join('左连接',"assetinstance","assetinstance.AssetId=asset.Id")
->groupBy("asset.Id")

【问题讨论】:

  • 你只有 1 个从 A 到 B 的引用 (int BId),计数怎么可能不是 1?
  • 我知道这是一个简单的例子,但请至少让它正确,这不是在 c# 中创建类的正确方法。
  • 您能否举例说明您正在使用哪些数据以及当您的源表有多行时您期望得到什么结果?另外,您已经尝试过什么?
  • @rst 我可以在表 A 中有许多具有相同 BId 的行,连接将是 a.BId=b.Id

标签: c# linq


【解决方案1】:

你的意思是这样的吗?

using System;
using System.Collections.Generic;
using System.Linq;

public class A 
{
    public int Id {get; set;}
    public int BId {get; set;}
    public string AName {get; set;}
}

public class B{
    public int Id {get; set;}
    public string description{get; set;}
}


public class Program
{
    private static List<A> _aList = new List<A>();  
    private static List<B> _bList = new List<B>();  

    public static void Main()
    {
        Seed();

        var query =
            from b in _bList
            group b by b.Id into g
            join a in _aList on g.FirstOrDefault().Id equals a.BId         
            select new { A_ID = a.Id, Cnt = g.Count(), AName = a.AName};

        Console.WriteLine("A_ID | count(Id) | AName");
        foreach(var row in query) 
        {
            Console.WriteLine(string.Join(" | ", new string[]{row.A_ID.ToString(), row.Cnt.ToString(), row.AName}));
        }
    }

    public static void Seed() 
    {       
        _aList.Add(new A{Id=1, BId=1, AName="A1"});
        _aList.Add(new A{Id=2, BId=1, AName="A2"});
        _aList.Add(new A{Id=3, BId=1, AName="A3"});
        _aList.Add(new A{Id=4, BId=2, AName="A4"});

        _bList.Add(new B{Id=1, description="B1"});
        _bList.Add(new B{Id=2, description="B2"});
    }
}

看我的小提琴https://dotnetfiddle.net/NlAX5V

【讨论】:

  • 几乎可以,但不是所有行都返回,因为加入,如果 b 存在,则只有 a 成员出现。如果 b 中的成员不存在,我没有来自 _aList.Add(new A { Id = 1, BId = 1, AName = "A1" }); 的成员_aList.Add(new A { Id = 2, BId = 1, AName = "A2" }); _aList.Add(new A { Id = 3, BId = 1, AName = "A3" }); _aList.Add(new A { Id = 4, BId = 3, AName = "A4" }); _bList.Add(new B { Id = 1, description = "B1" }); _bList.Add(new B { Id = 2, description = "B2" });
【解决方案2】:
var result= (from A in ListA
             join B in List B
             on A.ID equals B.ID
             select new {A,B})
             .GroupBy(x=>x.A.Id)
             .Select(x=>new
              {
                ID=x.Key
                count=x.Count(),
                AName=x.Select(z=>z.A.AName)
              }).ToList();

【讨论】:

  • 你好,和上面一样。如果 b 成员不存在,我将没有一行,例如 _bList.Add(new B{Id=3, description="B3"});而不是 _bList.Add(new B{Id=2, description="B2"});
  • A.BId= B.Id 需要更多的过度加入
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
相关资源
最近更新 更多