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

如何编写LINQ查询获取用户及其首篇文章?

解决方案

思路1:先分组取首篇文章时间,再关联查询

这种方式贴合你原始SQL的逻辑,先通过分组获取每个用户最早的文章创建时间,再关联用户表和文章表筛选对应数据,避免将所有用户字段加入GROUP BY:

// 先获取每个用户的首篇文章创建时间
var userFirstArticleDates = db.Articles
    .GroupBy(a => a.UserId)
    .Select(g => new 
    { 
        UserId = g.Key, 
        FirstCreatedAt = g.Min(a => a.CreatedAt) 
    });

// 关联用户、首篇时间和文章表,得到最终结果
var result = from u in db.Users
             join ufad in userFirstArticleDates on u.Id equals ufad.UserId
             join a in db.Articles on new { u.Id, ufad.FirstCreatedAt } equals new { a.UserId, a.CreatedAt }
             orderby u.Id, a.CreatedAt, a.Id
             select new 
             {
                 UserId = u.Id,
                 Username = u.Username,
                 ArticleId = a.Id,
                 FirstArticleCreatedAt = a.CreatedAt
             };

思路2:使用窗口函数筛选首篇文章

如果你的ORM支持窗口函数(比如EF Core 3.0及以上版本),可以用RowNumber()按用户分组、按创建时间排序,直接提取每个用户的第一篇文章,代码更简洁:

var result = db.Articles
    .Select(a => new 
    {
        UserId = a.User.Id,
        Username = a.User.Username,
        ArticleId = a.Id,
        CreatedAt = a.CreatedAt,
        // 按用户分组,按创建时间、文章ID升序排,标记行号
        RowNum = EF.Functions.RowNumber().Over(
            partitionBy: a.UserId, 
            orderBy: a.CreatedAt ascending, a.Id ascending)
    })
    .Where(x => x.RowNum == 1) // 只取每组的第一行(首篇文章)
    .OrderBy(x => x.UserId)
    .Select(x => new 
    {
        x.UserId,
        x.Username,
        x.ArticleId,
        FirstArticle = x.CreatedAt
    });

关于你之前代码的问题

你之前用new { user }作为分组键,LINQ会把整个User对象的所有字段都纳入分组条件,所以生成的SQL会包含所有用户字段的GROUP BY。要仅按Id分组,必须先通过分组拿到首篇文章的关键信息,再关联回用户表获取其他字段,而不是直接在分组中引用整个User对象。


内容的提问来源于stack exchange,提问作者glen-84

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:22:48