You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写LINQ查询:关联两表按A的Id分组统计关联行数(含PHP转LINQ)

嘿,这两个LINQ需求我帮你搞定!

问题1:A、B表关联分组查询

首先先明确实体类(和你给出的一致):

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

要实现按A的Id分组,展示A的Id、关联B表的行数、AName,这里推荐用左连接(确保所有A记录都能被统计,包括没有关联B的情况,此时B行数为0)。以下是两种常见的LINQ写法:

查询语法(更接近SQL,易读)

var result = from a in dbContext.A
             // 左连接A和B,把每个A对应的B集合分组
             join b in dbContext.B on a.BId equals b.Id into bGroup
             // 按A的Id和AName分组(同一Id的AName应该一致)
             group bGroup by new { a.Id, a.AName } into grouped
             select new
             {
                 AId = grouped.Key.Id,
                 // 统计分组内B的总数
                 BCount = grouped.SelectMany(b => b).Count(),
                 AName = grouped.Key.AName
             };

方法语法(链式调用,灵活)

var result = dbContext.A
    .GroupJoin(dbContext.B,
        a => a.BId,    // A的关联字段
        b => b.Id,     // B的关联字段
        (a, bGroup) => new { a.Id, a.AName, Bs = bGroup }) // 关联后组合A和对应的B集合
    .GroupBy(x => new { x.Id, x.AName }) // 按A的Id和AName分组
    .Select(g => new
    {
        AId = g.Key.Id,
        BCount = g.SelectMany(x => x.Bs).Count(),
        AName = g.Key.AName
    });

如果你的需求是只统计有关联B的A记录,把GroupJoin换成普通Join即可,不过左连接的场景更通用。


问题2:PHP查询转LINQ实现

先分析原PHP查询的核心逻辑:左连接asset和assetinstance表,按asset.Id分组,统计每个asset对应的instance数量,同时返回asset的多个字段。

首先假设对应的.NET实体类(你可以根据实际情况调整):

class Asset {
    public int Id { get; set; }
    public string AssetBundleID { get; set; }
    public string GUID { get; set; }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public int TexturesSize { get; set; }
    public int TexturesFileSize { get; set; }
    public int OthersSize { get; set; }
    public int OthersFileSize { get; set; }
}

class AssetInstance {
    public int Id { get; set; }
    public int AssetId { get; set; }
    // 其他字段按需添加
}

注意:原PHP查询的select里有重复的字段映射(比如多次asset.Name as Id、asset.id as Id),这在SQL里是冗余的,我在LINQ里保留了合理的字段映射,如果需要严格对应重复别名,可以自行调整。

以下是LINQ实现:

查询语法

var query = from asset in dbContext.Asset
            // 左连接asset和assetinstance
            join instance in dbContext.AssetInstance 
                on asset.Id equals instance.AssetId into instanceGroup
            from instance in instanceGroup.DefaultIfEmpty()
            // 按asset实体分组(因为asset.Id是主键,分组后每个组对应一个唯一的asset)
            group instance by asset into groupedAsset
            select new
            {
                Id = groupedAsset.Key.Id,
                AssetBundleID = groupedAsset.Key.AssetBundleID,
                GUID = groupedAsset.Key.GUID,
                Name = groupedAsset.Key.Name, // 原PHP重复映射为Id,若需保留请改为 Id = groupedAsset.Key.Name
                DisplayName = groupedAsset.Key.DisplayName,
                Description = groupedAsset.Key.Description,
                Category = groupedAsset.Key.Category,
                TexturesSize = groupedAsset.Key.TexturesSize,
                TexturesFileSize = groupedAsset.Key.TexturesFileSize,
                OthersSize = groupedAsset.Key.OthersSize,
                OthersFileSize = groupedAsset.Key.OthersFileSize,
                // 统计关联的instance数量(左连接后空实例不计入)
                InstancesCount = groupedAsset.Count(i => i != null)
            };

方法语法

var query = dbContext.Asset
    .GroupJoin(dbContext.AssetInstance,
        asset => asset.Id,
        instance => instance.AssetId,
        (asset, instances) => new { Asset = asset, Instances = instances })
    // 展开左连接的结果,空实例用DefaultIfEmpty()填充
    .SelectMany(x => x.Instances.DefaultIfEmpty(), (x, instance) => new { x.Asset, Instance = instance })
    // 按asset分组
    .GroupBy(x => x.Asset)
    .Select(g => new
    {
        Id = g.Key.Id,
        AssetBundleID = g.Key.AssetBundleID,
        GUID = g.Key.GUID,
        Name = g.Key.Name,
        DisplayName = g.Key.DisplayName,
        Description = g.Key.Description,
        Category = g.Key.Category,
        TexturesSize = g.Key.TexturesSize,
        TexturesFileSize = g.Key.TexturesFileSize,
        OthersSize = g.Key.OthersSize,
        OthersFileSize = g.Key.OthersFileSize,
        InstancesCount = g.Count(item => item.Instance != null)
    });

这个实现完全对应原PHP查询的逻辑:左连接、分组、统计实例数量,同时返回指定的asset字段。


内容的提问来源于stack exchange,提问作者kwestia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:04:52