如何使用EF Core Power Tools在API控制器中调用Insert存储过程
问题修正方案
你当前代码核心错误是对生成方法的参数类型、参数含义理解有误,误将不存在的实体字段作为参数传入,也没有正确处理输出参数类型,按以下步骤修正即可:
核心参数说明
InsertAttendeeAsync的几个特殊参数和实体属性无关,不要混淆:
id:类型为OutputParameter<int?>,是EF Core Power Tools生成的专用输出参数承载类型,对应存储过程的输入输出参数@id,插入新数据时用于接收生成的主键IDreturnValue:类型为OutputParameter<int>,可选参数,对应存储过程本身RETURN语句返回的整数状态值,不需要接收可以不传cancellationToken:类型为CancellationToken,是ASP.NET Core提供的请求取消令牌,用于在用户断开请求时自动取消数据库操作,不属于业务字段,直接从控制器方法绑定即可- 方法本身返回的
int值:是ExecuteSqlRawAsync返回的SQL执行受影响行数,不是新生成ID,也不是存储过程返回值
第一步:修正接口定义
你贴出的IKATSContextProcedures接口签名和实际实现不匹配,会直接导致编译报错,修正为和实现类一致的签名即可(注意引入OutputParameter、CancellationToken对应的命名空间):
using System; using System.Threading; using System.Threading.Tasks; // 引入OutputParameter所在命名空间,根据你项目中EF Core Power Tools生成代码的实际命名空间调整 using Microsoft.EntityFrameworkCore; public interface IKATSContextProcedures { Task<int> InsertAttendeeAsync( DateTime? dateCreated, DateTime? dateModified, string firstName, string lastName, string modifiedBy, int? person, int? type, OutputParameter<int?> id, OutputParameter<int> returnValue = null, CancellationToken cancellationToken = default); }
第二步:修正控制器方法
去掉多余的实体属性复制逻辑,正确实例化输出参数,从控制器方法接收取消令牌,调用完成后从输出参数实例中取值:
[HttpPost("InsertAttendee")] public async Task<IActionResult> InsertAttendeeAsync(Attendee1 request, CancellationToken cancellationToken) { // 实例化输出参数对象,用于接收存储过程返回的新生成主键ID var outputId = new OutputParameter<int?>(); // 需要接收存储过程RETURN状态值就实例化,不需要可以删除,调用时不传该参数即可 var returnValue = new OutputParameter<int>(); // 直接使用request对象的属性传参,不需要额外新建Attendee1实例复制属性 var affectedRows = await _context.GetProcedures().InsertAttendeeAsync( dateCreated: request.DateCreated, dateModified: request.DateModified, firstName: request.FirstName, lastName: request.LastName, modifiedBy: request.ModifiedBy, person: request.Person, type: request.Type, id: outputId, returnValue: returnValue, cancellationToken: cancellationToken ); // 调用完成后,outputId.Value就是存储过程返回的新参会人ID var newAttendeeId = outputId.Value; // 如需取存储过程RETURN值,访问returnValue.Value即可 // 按需返回结果,示例返回新生成ID和受影响行数 return Ok(new { Id = newAttendeeId, AffectedRows = affectedRows }); }
注意事项
- 禁止直接给
id、returnValue参数传普通int类型值,必须传入OutputParameter<T>实例,调用完成后从实例的Value属性取输出值 - 不需要接收存储过程RETURN状态值时,调用时可以省略
returnValue参数,方法会自动使用默认值null CancellationToken不要手动new实例,直接在控制器方法参数列表中声明,ASP.NET Core会自动绑定当前请求的取消令牌- 原代码中访问
Attendee1.returnvalue、Attendee1.cancellationtoken属于概念错误,Attendee1实体类中不存在这两个属性
内容的提问来源于stack exchange,提问作者Eric Tilton
相关产品推荐
相关产品推荐

