为什么此代码不执行存储过程并插入数据?

时间:2019-05-27 19:01:54

标签: c# sql-server tsql asp.net-core dapper

我这里列出了一个控制器,该控制器应该调用Dapper方法,但是我无法执行它。它不会引发任何异常,它会在try catch下进行重定向,但是该过程似乎未在运行,因为从未创建过任何新用户。

建立连接使用简单的内联.Query方法,但是一旦我尝试使用存储过程执行此操作,它就会失败。

型号:

    public class User
    {
        public int UserID { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Boolean ActiveB { get; set; }
    }

查看:

@model ScaleBase.Models.FullUser

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>User</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="OrganisationID" class="control-label"></label>
                <input asp-for="OrganisationID" class="form-control" />
                <span asp-validation-for="OrganisationID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ClientID" class="control-label"></label>
                <input asp-for="ClientID" class="form-control" />
                <span asp-validation-for="ClientID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="TeamID" class="control-label"></label>
                <input asp-for="TeamID" class="form-control" />
                <span asp-validation-for="TeamID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Email" class="control-label"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Username" class="control-label"></label>
                <input asp-for="Username" class="form-control" />
                <span asp-validation-for="Username" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Password" class="control-label"></label>
                <input asp-for="Password" type="password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="FirstName" class="control-label"></label>
                <input asp-for="FirstName" class="form-control" />
                <span asp-validation-for="FirstName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="LastName" class="control-label"></label>
                <input asp-for="LastName" class="form-control" />
                <span asp-validation-for="LastName" class="text-danger"></span>
            </div>            
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input asp-for="ActiveB" /> @Html.DisplayNameFor(model => model.ActiveB)
                    </label>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

控制器:

public ActionResult Create(IFormCollection collection)
{
        try
        {
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("@Organisation", collection["OrganisationID"]);
            parameters.Add("@ClientID1", collection["ClientID"]);
            parameters.Add("@Team", collection["TeamID"]);
            parameters.Add("@Email", collection["Email"]);
            parameters.Add("@UserName", collection["UserName"]);
            parameters.Add("@Password", collection["Password"]);
            parameters.Add("@FirstName", collection["FirstName"]);
            parameters.Add("@LastName", collection["LastName"]);

            var affectedRows = _dapperRepo.CreateUser(parameters);

            return RedirectToAction(nameof(Index));
        }
        catch (Exception)
        {
            throw;
        }
    }

Dapper仓库:

    public async Task<User> CreateUser(DynamicParameters parameters)
    {
        using (IDbConnection conn = Connection)
        {            
            string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";
            conn.Open();
            var result = await conn.QueryAsync(sproc, parameters, commandType: CommandType.StoredProcedure);
            return result.FirstOrDefault();
        }   
    }

存储过程:

BEGIN TRY 
    BEGIN TRANSACTION NewUser
        DECLARE @salt UNIQUEIDENTIFIER = NEWID()

        INSERT INTO [dbo].[User] (Username, Email, FirstName, LastName, Password, Salt, Active) 
        VALUES (@UserName, @Email, @FirstName, @LastName, HASHBYTES('SHA2_512', @Password+CAST(@salt AS NVARCHAR(36))), @salt, 1)

        INSERT INTO [dbo].[UserOrganisations] (UserID, OrganisationID) 
        VALUES (IDENT_CURRENT('User'), @Organisation)

        INSERT INTO [dbo].[UserClients] (UserID, ClientID) 
        VALUES (IDENT_CURRENT('User'), @Client1)

        IF @Client2 IS NOT NULL
        BEGIN 
            INSERT INTO [dbo].[UserClients] (UserID, ClientID) 
            VALUES (IDENT_CURRENT('User'), @Client2)
        END

        IF @Client3 IS NOT NULL
        BEGIN 
            INSERT INTO [dbo].[UserClients] (UserID, ClientID) 
            VALUES (IDENT_CURRENT('User'), @Client3)
        END

        IF @Client4 IS NOT NULL
        BEGIN 
            INSERT INTO [dbo].[UserClients] (UserID, ClientID) 
            VALUES (IDENT_CURRENT('User'), @Client4)
        END

        IF @Client5 IS NOT NULL
        BEGIN 
            INSERT INTO [dbo].[UserClients] (UserID, ClientID) 
            VALUES (IDENT_CURRENT('User'), @Client5)
        END

        INSERT INTO [dbo].[UserTeams] (UserID, TeamID) 
        VALUES (IDENT_CURRENT('User'), @Team)

        INSERT INTO [dbo].[UserPermission] (UserID, HolidayCount, HolidayUsed, TemplateID, ConfigState1, ConfigState2, ConfigState3, ConfigState4, ConfigState5) 
        VALUES (IDENT_CURRENT('User'), @Holiday, 0, 1, 255, null, null, null, null)

        INSERT INTO [dbo].[UserTime] (UserID, Scale, StartTime, EndTime) 
        VALUES (IDENT_CURRENT('User'), 1, @StartTime, @EndTime)

        COMMIT TRANSACTION NewUser

        PRINT 'Success'

        SELECT 
            [UserID], [Username], [Email], [Firstname], [Lastname], [Active] 
        FROM 
            [User] 
        WHERE 
            [UserID] = IDENT_CURRENT('User')
END TRY
BEGIN CATCH
    IF (@@TRANCOUNT > 0)
    BEGIN
        ROLLBACK TRANSACTION NewUser
        PRINT 'Failed'
    END 

    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

        RETURN 'Error'
END CATCH

3 个答案:

答案 0 :(得分:2)

使用commandType: CommandType.StoredProcedure时,您只需要指定存储过程名称-因此,无需

string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";

只写

string sproc = "sproc_NewUser";

答案 1 :(得分:0)

使用QueryAsync而不是使用ExecuteAsync来返回命令更改的行数。

您也不会等待异步呼叫。那不是好习惯。试试这个:

var affectedRows = await _dapperRepo.CreateUser(parameters);

var result = await conn.ExecuteAsync(sproc, parameters, commandType: CommandType.StoredProcedure);

您可以参考以下内容:https://dapper-tutorial.net/async#executeasync

答案 2 :(得分:0)

声明存储过程中列出的所有参数。 @Client2, @ClientID3等会导致未声明的参数错误。

将其实现更改为.ExecuteAsync并在控制器中执行似乎可以解决此问题。

public Async Task<IActionResult> Create(IFormCollection collection)
{
        try
        {
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("@Organisation", collection["OrganisationID"]);
            parameters.Add("@ClientID1", collection["ClientID"]);
            parameters.Add("@Team", collection["TeamID"]);
            parameters.Add("@Email", collection["Email"]);
            parameters.Add("@UserName", collection["UserName"]);
            parameters.Add("@Password", collection["Password"]);
            parameters.Add("@FirstName", collection["FirstName"]);
            parameters.Add("@LastName", collection["LastName"]);

            var affectedRows = _dapperRepo.CreateUser(parameters);
            using (IDbConnection conn = Connection)
            {            
                string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";
                conn.Open();
                var result = await conn.QueryAsync(sproc, parameters, commandType: CommandType.StoredProcedure);
                var result2 = result.FirstOrDefault();
            }   
            return RedirectToAction(nameof(Index));
        }
        catch (Exception)
        {
            throw;
        }
    }