【问题标题】:Exe sproc with TVP and un-tabled parameters in Dapper?Dapper中带有TVP和未列出参数的Exe sproc?
【发布时间】:2017-09-26 17:23:16
【问题描述】:

我有一个存储过程(我们将其称为 usp_SaveQuestionAnswer),它插入/更新申请人对申请中任何给定问题的回答,它需要类似于以下的参数:

@answeredQuestionGuid UNIQUEIDENTIFIER,
@questionGuid UNIQUEIDENTIFIER,
@applicationId INT,
@applicantID INT,
@answerData tvp_AnswerData READONLY

而 tvp_AnswerData 定义为:

answerGuid UNIQUEIDENTIFIER,
answerTypeId INT,
answerValue VARCHAR(300),
answerBoolValue BIT

sproc 接受参数,并以字符串的形式返回错误,表明数据无效(类型错误,不应为 null 等),或者根本不返回任何内容。

如何做到这一点的明显答案(根据this)将是DynamicParameters,因为.Net Core不支持DataTables——为tvp_AnswerData构建一个DynamicParameters对象,然后是第二个DynamicParameters对象(称为dynamicParamsObject) 用于整个参数列表,将 tvp_AnswerData DynamicParameters 对象传递到其中,然后使用以下内容执行存储过程:

var result = _db.Query
(
    "usp_SaveQuestionAnswer",
    dynamicParamsObject,
    commandType: CommandType.StoredProcedure
);

不幸的是,据我所知,DynamicParameters 不知道如何处理 DynamicParameters 类型的参数。

我做错了吗?除了逐字写出 sql 命令之外,Dapper 是否可以处理将 TVP 与其他参数一起传递给 sproc 的方法,或者我是否可以选择重写 DB 或使用 Dapper 以外的其他东西(例如 SqlCommand)?

【问题讨论】:

    标签: c# asp.net-core .net-core dapper


    【解决方案1】:

    这并不漂亮,但有可能。下面是一个随机 sn-p 的例子:

    CREATE TYPE [dbo].[DeptType] AS TABLE(
        [DeptId] [int] NULL,
        [DeptName] [varchar](100) NULL
    )
    GO
    
    CREATE PROCEDURE [dbo].[InsertDepartment]
    @InsertDept_TVP DeptType READONLY
    AS
    INSERT INTO Department(DepartmentID,DepartmentName)
    SELECT * FROM @InsertDept_TVP;
    GO
    
    [Test]
    public void Test()
    {
        var conn = new SqlConnection(@"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo");
        conn.Open();
    
        var x = new DataTable();
        x.SetTypeName("DeptType");
        x.Columns.Add("DeptId", typeof(int));
        x.Columns.Add("DeptName", typeof(string));
    
        var row = x.NewRow();
        row["DeptId"] = 1;
        row["DeptName"] = "Foo";
        x.Rows.Add(row);
    
        var row2 = x.NewRow();
        row2["DeptId"] = 2;
        row2["DeptName"] = "Bar";
        x.Rows.Add(row2);
    
        conn.Execute("InsertDepartment", new { InsertDept_TVP = x.AsTableValuedParameter("DeptType") }, commandType: CommandType.StoredProcedure);
    }
    

    【讨论】:

    • 这也是我的想法,或者,更难看,循环通过tvp_AnswerData
    • 不幸的是,.Net Core 中不存在 DataTable,并且建议的解决方法 SqlDataRecord 不是 DynamicParameters 中支持的参数类型。 :(
    • 我个人倾向于尽可能远离存储过程,并将所有逻辑保留在代码中。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    相关资源
    最近更新 更多