Dotnetcore3.1执行Stored Procedure及处理多表混合返回结果的问题
解决方案
问题1:存储过程返回混合字段的接收结构
你当前的写法存在问题,IQueryable<AppUser>只能映射AppUser实体对应的字段,无法存储CourseMarks表的字段和计算字段TotalMarks,需要自定义专用的DTO(数据传输对象)来接收返回结果:
- 定义匹配存储过程返回字段的DTO
public class UserCourseMarkDto { public int ID { get; set; } public string Name { get; set; } public string CourseName { get; set; } public string CourseResult { get; set; } public int TotalMarks { get; set; } }
- 在DbContext中注册该DTO为无键实体(存储过程返回结果无唯一主键,需要配置为无键实体才能被EF Core映射)
- 首先在DbContext类中添加对应的DbSet:
public DbSet<UserCourseMarkDto> UserCourseMarks { get; set; }
- 在
OnModelCreating方法中添加无键配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 保留原有其他配置 modelBuilder.Entity<UserCourseMarkDto>().HasNoKey(); }
- 修正存储过程调用代码
var userId= new SqlParameter("@UserId",2); // 用无键实体的DbSet调用存储过程,ToList()会触发查询实际执行 var userCourseMarks = _dbContext.UserCourseMarks .FromSqlRaw("exec dbo.GetCourseAndCourseMark @UserId", userId) .IgnoreQueryFilters() .ToList();
额外提示:你提供的存储过程SQL存在语法错误,
CM.CourseResult后缺少逗号,修正后如下:
SELECT U.[Name],CM.CourseName , CM.CourseResult, -- 此处补全逗号 U.ID, ISNULL(SUM(CM.Marks),0) AS TotalMarks FROM dbo.[AppUser] U LEFT JOIN dbo.CourseMarks CM ON U.ID = CM.UserID WHERE U.ID = @UserId GROUP BY U.[Name], U.ID, CM.CourseName , CM.CourseResult ;
问题2:将结果转换为JSON格式
分两种常见场景处理:
- 如果是在ASP.NET Core 3.1的Controller接口中返回,框架自带JSON序列化能力,直接把查询结果作为返回值即可:
public IActionResult GetUserCourseMark(int userId) { // 上述查询逻辑省略 return Ok(userCourseMarks); }
- 如果需要手动序列化生成JSON字符串:
- 用系统自带的
System.Text.Json实现:
using System.Text.Json; string jsonResult = JsonSerializer.Serialize(userCourseMarks);- 如果使用Newtonsoft.Json(需先安装Newtonsoft.Json NuGet包):
using Newtonsoft.Json; string jsonResult = JsonConvert.SerializeObject(userCourseMarks); - 用系统自带的
内容的提问来源于stack exchange,提问作者Illep
相关产品推荐
相关产品推荐

