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

如何用LINQ实现IQueryable多条件过滤及去重取最新Timestamp?

解决LINQ多条件过滤+去重+取最新时间戳的问题

我看了你当前的代码,问题主要出在这几个地方:

  • 循环遍历每个版本会触发多次数据库查询,效率很低
  • GroupBy(x => x.CompanyName).SelectMany(y => y) 其实又把分组后的结果拆回了原集合,根本没实现去重逻辑
  • 完全没处理「保留每个CompanyName对应最新Timestamp记录」的需求,计数也没基于去重后的结果

下面是符合你所有需求的实现方案,用LINQ一步到位完成所有操作:

public List<ReleaseStatistics> GetReleaseStatistics(IQueryable<InstallationInformation> input, IQueryable<DBContext.Version> mapping)
{
    // 1. 关联版本映射和安装信息,一次性过滤出匹配ProductVersion的记录
    var filteredData = from info in input
                       join version in mapping on info.ProductVersion equals version.VersionNumber
                       select new { info, version };

    // 2. 按「公司名+版本名」分组,每组取Timestamp最新的那条记录
    var groupedLatestRecords = filteredData
        .GroupBy(x => new { x.info.CompanyName, x.version.ReleaseName })
        .Select(g => g.OrderByDescending(x => x.info.Timestamp).First());

    // 3. 按版本名分组统计去重后的客户数,转换为目标列表
    var releaseStats = groupedLatestRecords
        .GroupBy(x => x.version.ReleaseName)
        .Select(g => new ReleaseStatistics
        {
            ReleaseVersion = g.Key,
            CustomerCount = g.Count()
        })
        .ToList();

    return releaseStats;
}

代码逻辑说明:

  • 关联过滤:用join把安装信息和版本映射关联,一次性筛选出所有匹配版本的记录,避免循环多次查询数据库
  • 取最新记录:按「公司名+版本名」分组,每组内按Timestamp倒序排列后取第一条,确保每个公司对应版本只保留最新的那条数据
  • 统计转换:按版本名分组,统计每组的数量(也就是去重后的客户数),直接转换为ReleaseStatistics列表返回

如果想进一步优化(避免两次GroupBy),也可以用这种写法:

public List<ReleaseStatistics> GetReleaseStatistics(IQueryable<InstallationInformation> input, IQueryable<DBContext.Version> mapping)
{
    var releaseStats = input
        .Join(mapping, 
              info => info.ProductVersion, 
              version => version.VersionNumber, 
              (info, version) => new { info, version })
        .GroupBy(x => new { x.info.CompanyName, x.version.ReleaseName })
        .Select(g => new 
        {
            ReleaseName = g.Key.ReleaseName,
            LatestTimestamp = g.Max(x => x.info.Timestamp)
        })
        .GroupBy(x => x.ReleaseName)
        .Select(g => new ReleaseStatistics
        {
            ReleaseVersion = g.Key,
            CustomerCount = g.Count()
        })
        .ToList();

    return releaseStats;
}

这两种写法都能满足你的全部需求:版本过滤、CompanyName去重、保留最新Timestamp、统计客户数并返回列表,而且都是基于IQueryable在数据库层面执行查询,性能比你原来的循环写法高效得多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:42:51