ASP.Net Core 3.1 MVC调用存储过程时触发InvalidOperationException异常的解决方案咨询
解决EF Core FromSqlRaw执行存储过程时的"Required column 'Id' not present"异常
首先咱们先理清楚报错的根源:你用的FromSqlRaw是EF Core专门用来查询数据并映射到实体类的方法,它默认会检查返回的结果集是否包含实体所有必填属性(比如你的Visit实体的主键Id)。但你的存储过程是做插入操作的,默认不会返回包含Id的结果集,所以EF Core就抛出了这个异常。
针对你要保留现有数据和表结构的需求,给你两个最贴合场景的解决办法:
方法一:改用ExecuteSqlRaw执行非查询操作
既然你的操作是写入数据(属于非查询操作),完全没必要用FromSqlRaw。EF Core提供了专门执行非查询命令的ExecuteSqlRaw方法,它不会要求结果集匹配实体结构,完美避开列检查。
把你的代码改成这样就行:
_context.Database.ExecuteSqlRaw("exec VisitApi_RecordVisit @User", userParam);
这个方法直接执行存储过程,不关心返回结果,不需要修改存储过程或表结构,是最适合你的方案。
方法二:修改存储过程,返回插入的Id列
如果你因为某些限制必须用FromSqlRaw,可以修改存储过程,让它在插入完成后返回刚生成的Id值,这样EF Core就能拿到它需要的列了。
比如在SQL Server的存储过程末尾加上这段代码(假设Id是自增主键):
SELECT Id FROM Visit WHERE Id = SCOPE_IDENTITY();
修改后存储过程执行会返回包含Id的结果集,FromSqlRaw就能正常映射到Visit实体,不会再抛出异常。
为什么不推荐修改实体配置(比如HasNoKey)?
你之前尝试的HasNoKey()会让EF Core认为这个实体没有主键,后续执行数据库迁移时,EF会要求你删除原有的主键列,这显然和你要保留现有数据的需求冲突,所以这个方法不适合你的场景。
内容的提问来源于stack exchange,提问作者Zap_00
相关产品推荐
相关产品推荐

