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

能否无需将自定义模型加入DbContext,映射EF Core存储过程结果至非实体模型?

无需DbSet,将EF Core存储过程结果映射到非实体模型

方案1:EF Core 7+ 原生SqlQuery方法

EF Core 7及以上版本提供了Database.SqlQuery<T>方法,直接支持查询非实体类型,无需在DbContext中注册DbSet<T>。

修改你的Controller代码如下:

// 调用存储过程并获取结果(参数化查询避免SQL注入)
var spResults = await _context.Database.SqlQueryRaw<ModelSpDto>(
    "EXECUTE dbo.storedProcedure @UserId",
    new SqlParameter("@UserId", request.UserId)
).ToListAsync();

// 排序
var sortedResults = spResults.OrderByDescending(x => x.DateCreated).ToList();

// 分页
IPagedList<ModelSpDto> pagingData = await sortedResults.ToPagedListAsync(
    pageNumber: request.PageNumber, 
    pageSize: request.PageSize
);

// 映射响应
response.PagingData = pagingData.ToMappedPagedList<ModelSpDto, ModelSp2Dto>(_mapper);

方案2:旧版EF Core(低于7)用ADO.NET+映射

如果你的EF Core版本低于7,可以直接用ADO.NET执行存储过程,再将结果映射到ModelSpDto:

手动映射写法

var spResults = new List<ModelSpDto>();
var connection = _context.Database.GetDbConnection();

try
{
    await connection.OpenAsync();
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "dbo.storedProcedure";
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add(new SqlParameter("@UserId", request.UserId));

        using (var reader = await command.ExecuteReaderAsync())
        {
            while (await reader.ReadAsync())
            {
                spResults.Add(new ModelSpDto
                {
                    DateCreated = reader.GetDateTime(reader.GetOrdinal("DateCreated")),
                    // 按存储过程返回的列名,依次映射其他属性
                });
            }
        }
    }
}
finally
{
    await connection.CloseAsync();
}

// 后续排序、分页、映射逻辑和方案1一致
var sortedResults = spResults.OrderByDescending(x => x.DateCreated).ToList();
IPagedList<ModelSpDto> pagingData = await sortedResults.ToPagedListAsync(
    pageNumber: request.PageNumber, 
    pageSize: request.PageSize
);
response.PagingData = pagingData.ToMappedPagedList<ModelSpDto, ModelSp2Dto>(_mapper);

用Dapper简化映射

如果觉得手动映射繁琐,可以引入Dapper简化操作(需先通过NuGet安装Dapper包):

var connection = _context.Database.GetDbConnection();
await connection.OpenAsync();

var spResults = await connection.QueryAsync<ModelSpDto>(
    "dbo.storedProcedure",
    new { UserId = request.UserId },
    commandType: CommandType.StoredProcedure
);

await connection.CloseAsync();

// 后续排序、分页、映射逻辑同上

关键注意事项

  • 必须使用参数化查询,禁止直接拼接参数,防止SQL注入风险
  • ModelSpDto的属性名称、类型要和存储过程返回的列名、类型严格匹配,否则会映射失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:46:26