首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用EF Core从存储过程中获取插入记录的id值

如何使用EF Core从存储过程中获取插入记录的id值
EN

Stack Overflow用户
提问于 2021-07-30 20:19:29
回答 3查看 417关注 0票数 2

我正在使用record 5,并且很难获得我插入到表中的记录的userId。我尝试过不同的方法,但我没有运气。我得到的是一个-1,我知道的是行受影响。我似乎无法检索UserID,它被声明为存储过程的OUTPUT参数。

存储过程:

代码语言:javascript
运行
复制
ALTER PROCEDURE [dbo].[User.Save]
    (@Return_Code  INT OUTPUT,
     @Error_Description_Code NVARCHAR(50) OUTPUT,
     @idCallerSite INT = 0, --default if not specified
     @idCaller     INT = 0,
     @idUser       INT OUTPUT, 
     @firstName     NVARCHAR(50),
     @middleName    NVARCHAR(50),
     @lastName      NVARCHAR(50),
     @preferredName NVARCHAR(50),
     @username      NVARCHAR(512),
     @password      NVARCHAR(512),
     @isActive      BIT,
     @isSalesperson BIT,
     @userPreferences NVARCHAR(512),
     @phoneNumber     NVARCHAR(25),
     @phoneFax        NVARCHAR(25),
     @email           NVARCHAR(255),
     @photo           NVARCHAR(255),
     @lastEditedBy    INT)
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @idPermission INT  -- define the permission required to perform this function
    SET @idPermission = 141
    
    /* 
    validate uniqueness
    */
    IF (SELECT COUNT(1)
        FROM Users
        WHERE SiteID = @idCallerSite
          AND (username = @username)
          AND (@idUser IS NULL OR @idUser <> UserID)) > 0
    BEGIN
        SET @Return_Code = 2
        SET @Error_Description_Code = 'UserSave_UserNotUnique'
        RETURN 1 
    END

    /*
    insert/update the user
    */

    IF (@idUser = 0 OR @idUser IS NULL)
    BEGIN
        -- insert the new user
        INSERT INTO Users (SiteID, firstName, middleName, lastName,
                           preferredName, username,
                           HashedPassword, isActive, IsSalesperson,
                           UserPreferences, PhoneNumber, FaxNumber,
                           EmailAddress, Photo, LastEditedBy)
        VALUES (@idCallerSite, @firstName, @middleName, @lastName,
                @preferredName, @username, 
                dbo.GetHashedString('SHA1', @password), @isActive, @isSalesperson,
                @userPreferences, @phoneNumber, @phoneFax,
                @email, @photo, @lastEditedBy)

        /*
        get the new user's id
        */

        SET @idUser = SCOPE_IDENTITY()
        SELECT @idUser

        -- return successfully
        SET @Return_Code = 0 --(0 is 'success')
        SET @Error_Description_Code = ''
    END

控制器呼叫

代码语言:javascript
运行
复制
var retCode = new SqlParameter { ParameterName = "@Return_Code", Value = null, SqlDbType = (SqlDbType.Int), Direction = System.Data.ParameterDirection.Output };

var errorDesc = new SqlParameter { ParameterName = "@Error_Description_Code", Value = null, SqlDbType = SqlDbType.NVarChar, Size = 50, Direction = System.Data.ParameterDirection.Output };
var idCallerSite = new SqlParameter { ParameterName = "@idCallerSite", Value = 1, SqlDbType = (SqlDbType.Int), Direction = System.Data.ParameterDirection.Input };
var idCaller = new SqlParameter { ParameterName = "@idCaller", Value = 0, SqlDbType = (SqlDbType.Int), Direction = System.Data.ParameterDirection.Input };
var idUser = new SqlParameter { ParameterName = "@idUser", Value = user.UserID, SqlDbType = (SqlDbType.Int), Direction = System.Data.ParameterDirection.Output };
var fName = new SqlParameter { ParameterName = "@firstName", Value = user.FirstName.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 50, Direction = System.Data.ParameterDirection.Input };
var mName = new SqlParameter { ParameterName = "@middleName", Value = user.MiddleName.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 50, Direction = System.Data.ParameterDirection.Input };
var lName = new SqlParameter { ParameterName = "@lastName", Value = user.LastName.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 50, Direction = System.Data.ParameterDirection.Input };
var pName = new SqlParameter { ParameterName = "@preferredName", Value = user.PreferredName.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 50, Direction = System.Data.ParameterDirection.Input };
var userName = new SqlParameter { ParameterName = "@username", Value = user.UserName.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 512, Direction = System.Data.ParameterDirection.Input };
var password = new SqlParameter { ParameterName = "@password", Value = user.HashedPassword.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 512, Direction = System.Data.ParameterDirection.Input };
var isActive = new SqlParameter { ParameterName = "@isActive", Value = user.IsActive, SqlDbType = (SqlDbType.Bit), Direction = System.Data.ParameterDirection.Input };
var isSalesperson = new SqlParameter { ParameterName = "@isSalesperson", Value = user.IsSalesperson, SqlDbType = (SqlDbType.Bit), Direction = System.Data.ParameterDirection.Input };
var userPref = new SqlParameter { ParameterName = "@userPreferences", Value = user.UserPreferences.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 512, Direction = System.Data.ParameterDirection.Input };
var phone = new SqlParameter { ParameterName = "@phoneNumber", Value = user.PhoneNumber.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 25, Direction = System.Data.ParameterDirection.Input };
var fax = new SqlParameter { ParameterName = "@phoneFax", Value = user.FaxNumber.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 25, Direction = System.Data.ParameterDirection.Input };
var email = new SqlParameter { ParameterName = "@email", Value = user.EmailAddress.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 255, Direction = System.Data.ParameterDirection.Input };
var photo = new SqlParameter { ParameterName = "@photo", Value = user.Photo.ToString(), SqlDbType = SqlDbType.NVarChar, Size = 255, Direction = System.Data.ParameterDirection.Input };
var lastEditedBy = new SqlParameter { ParameterName = "@lastEditedBy", Value = user.LastEditedBy, SqlDbType = (SqlDbType.Int), Direction = System.Data.ParameterDirection.Input };

var _user = await _db.Database.ExecuteSqlRawAsync("EXEC [dbo].[User.Save] @Return_Code, @Error_Description_Code, @idCallerSite, @idCaller, @idUser OUT, @firstName, @middleName, @lastName, @preferredName, @username, @password, @isActive, @isSalesperson, @userPreferences, @phoneNumber, @phoneFax, @email, @photo, @lastEditedBy", retCode, errorDesc, idCallerSite, idCaller, idUser, fName, mName, lName, pName, userName, password, isActive, isSalesperson, userPref, phone, fax, email, photo, lastEditedBy);

return Ok(_user);

我使用了.FromSql并得到了以下错误。

代码语言:javascript
运行
复制
var _user = _db.Users.FromSqlRaw("EXEC [dbo].[User.Save] @Return_Code, @Error_Description_Code, @idCallerSite, @idCaller, @idUser OUT, @firstName, @middleName, @lastName, @preferredName, @username, @password, @isActive, @isSalesperson, @userPreferences, @phoneNumber, @phoneFax, @email, @photo, @lastEditedBy", retCode, errorDesc, idCallerSite, idCaller, idUser, fName, mName, lName, pName, userName, password, isActive, isSalesperson, userPref, phone, fax, email, photo, lastEditedBy);

System.InvalidOperationException:在“FromSql”操作的结果中不存在所需的列“UserID”。

在Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable1.BuildIndexMap(IReadOnlyList1 columnNames,DbDataReader dataReader)

在Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4操作时,Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable1.AsyncEnumerator.MoveNextAsync()

在Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternalT

在Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternalT

在Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncEnumerable(ActionContext上下文中,ObjectResult结果、对象asyncEnumerable、Func`2‘2阅读器)

在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_TFilter,TFilterAsync

(在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed上下文中)

在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNextTFilter,TFilterAsync

在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|27_0(ResourceInvoker调用程序,任务lastTask,状态下一步,范围范围,对象状态,布尔isCompleted)

在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker调用程序,任务lastTask,状态下一步,范围范围,对象状态,布尔isCompleted)

在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker调用程序,任务任务,IDisposable作用域)

在Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint端点,任务requestTask,ILogger记录器)

(在Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext上下文中)

在Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)

在Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext,ISwaggerProvider swaggerProvider)

(在Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext上下文中)

标题:

代码语言:javascript
运行
复制
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 301
Content-Type: application/json
Cookie: fblo_329420117573382=y
Host: localhost:62374
Referer: http://localhost:62374/swagger/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
Origin: http://localhost:62374
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
EN

回答 3

Stack Overflow用户

发布于 2021-07-30 21:13:24

只能使用输出参数idUser获取记录Id。

代码语言:javascript
运行
复制
_db.Database.ExecuteSqlRaw(....);

var id=0;

if (idUser.Value != DBNull.Value)
     {
        id = (int) idUser.Value;
     }
return Ok(id);

并修复存储过程。删除SELECT @idUser,只留下

代码语言:javascript
运行
复制
 SET @idUser = SCOPE_IDENTITY()

如果sp包含SELECT,Database.ExecuteSqlRaw总是返回-1;

票数 0
EN

Stack Overflow用户

发布于 2021-07-30 21:14:11

我修正了使用所有字段执行select语句的问题,然后从结果集中提取UserID。谢谢你@Progman的帮助。是你的建议帮助了我。

票数 0
EN

Stack Overflow用户

发布于 2021-08-01 04:24:56

实体框架要求至少存在主键,所以您需要这样做

代码语言:javascript
运行
复制
SET @idUser = SCOPE_IDENTITY();
SELECT UserID = @idUser;

然而,这只为您提供一个字段,它将不会为您提供任何其他列。要获得其他列,只需OUTPUT所有内容(不需要联接)

代码语言:javascript
运行
复制
INSERT INTO Users (SiteID, firstName,
.........
OUTPUT inserted.ID, inserted.SiteID, inserted.firstName
.........
        VALUES (@idCallerSite, @firstName
.........

注意,用于调用存储过程的语法并不理想,因为它依赖于参数位置而不是名称。相反,使用EXEC [dbo].[User.Save] @Return_Code = @Return_Code OUTPUT, @Error_Description_Code = @Error_Description_Code, @idCallerSite = @idCallerSite ...,您还需要在输出参数上指定OUTPUT,如下所示.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68596706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档