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

如何在Entity Framework中编写关联查询?含SQL转EF Core及规范模式需求

EF Core 原生查询实现

你的SQL逻辑是找出每个Platform下状态为Complete且UpdateDate为该平台最新的Release记录,以下是几种对应的EF Core实现方式:

方式一:直接对应原SQL的子查询写法

这是最贴近原SQL结构的LINQ实现,EF Core会将其转换为等价的SQL语句:

var latestCompleteReleases = await dbContext.Releases
    .Where(r1 => 
        r1.Status == "Complete" &&
        r1.UpdateDate == dbContext.Releases
            .Where(r2 => r2.Platform == r1.Platform && r2.Status == "Complete")
            .Max(r2 => r2.UpdateDate))
    .ToListAsync();

方式二:窗口函数(ROW_NUMBER)实现

对于大数据量场景,窗口函数的性能通常更优(EF Core 3.0+支持):

// 先给每个Platform下的Complete记录按UpdateDate降序排名
var rankedReleases = dbContext.Releases
    .Where(r => r.Status == "Complete")
    .Select(r => new
    {
        Release = r,
        RowRank = EF.Functions.RowNumber()
            .Over(partitionBy: r.Platform, orderBy: r.UpdateDate descending)
    });

// 筛选出每个Platform下排名第一的记录(即最新的)
var latestCompleteReleases = await rankedReleases
    .Where(x => x.RowRank == 1)
    .Select(x => x.Release)
    .ToListAsync();

规范模式实现

规范模式用于封装可复用的查询逻辑,以下是针对该需求的实现:

1. 基于第三方库(Ardalis.Specification)的实现

这是社区常用的规范模式库,使用起来更便捷:

using Ardalis.Specification;

public class LatestCompleteReleaseByPlatformSpec : Specification<Release>
{
    public LatestCompleteReleaseByPlatformSpec()
    {
        // 基础过滤:只包含状态为Complete的记录
        Query.Where(r => r.Status == "Complete");

        // 子查询条件:当前记录的UpdateDate是对应Platform下Complete状态的最新日期
        Query.Where(r => 
            r.UpdateDate == Query
                .Where(r2 => r2.Platform == r.Platform && r2.Status == "Complete")
                .Max(r2 => r2.UpdateDate));
    }
}

在Repository中使用该规范:

public class ReleaseRepository : IReleaseRepository
{
    private readonly AppDbContext _dbContext;

    public ReleaseRepository(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<List<Release>> GetLatestCompleteReleasesAsync()
    {
        var spec = new LatestCompleteReleaseByPlatformSpec();
        return await _dbContext.Releases.WithSpecification(spec).ToListAsync();
    }
}

2. 自定义规范(不依赖第三方库)

如果不想引入第三方库,可自行实现简单的规范接口:

// 定义规范接口
public interface ISpecification<T>
{
    Expression<Func<T, bool>> Criteria { get; }
}

// 实现查询规范
public class LatestCompleteReleaseByPlatformSpec : ISpecification<Release>
{
    private readonly AppDbContext _dbContext;

    public LatestCompleteReleaseByPlatformSpec(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Expression<Func<Release, bool>> Criteria => 
        r => r.Status == "Complete" &&
             r.UpdateDate == _dbContext.Releases
                 .Where(r2 => r2.Platform == r.Platform && r2.Status == "Complete")
                 .Max(r2 => r2.UpdateDate);
}

// Repository中使用规范
public async Task<List<Release>> GetLatestCompleteReleasesAsync()
{
    var spec = new LatestCompleteReleaseByPlatformSpec(_dbContext);
    return await _dbContext.Releases.Where(spec.Criteria).ToListAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:55:27