【问题标题】:Dapper / SQL Server : passing TVP to stored procedure with needed fields onlyDapper / SQL Server:仅将 TVP 传递给具有所需字段的存储过程
【发布时间】:2020-08-18 20:39:39
【问题描述】:

我需要将一组项目传递给存储过程。存储过程将它们插入到多个表中。我使用声明的自定义用户类型的表值参数。

TVP 类型:

CREATE TYPE [dbo].[Type1] AS TABLE
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Field1] [nvarchar](256) NOT NULL,
    [Field2] [int] NOT NULL,

    PRIMARY KEY NONCLUSTERED ([Id] ASC)
            WITH (IGNORE_DUP_KEY = OFF)
)

这是我使用的代码:

var dataTable = new List<SqlDataRecord>();
SqlMetaData[] metaData =
{
    new SqlMetaData("Field1", SqlDbType.NVarChar, 256),
    new SqlMetaData("Field2", SqlDbType.Int),
};

foreach (var item in items)
{
    var record = new SqlDataRecord(metaData);
    record.SetValue(0, item.Field1);
    record.SetValue(1, item.Field2);
    dataTable.Add(record);
}
var parameters = new DynamicParameters(new
{
    Items = dataTable.AsTableValuedParameter()
});

await conn.QueryAsync(
    sql: "DoSomeJob_Sproc",
    param: parameters,
    commandType: CommandType.StoredProcedure);

这里的问题是 TVP 类型的标识符列在此处插入新项目时不能(实际上也不需要)传递。但是如果我没有在记录元数据中指定它,我会得到一个错误

尝试传递具有 2 列的表值参数,其中相应的用户定义的表类型需要 3 列。

问题是:有没有办法明确地指定我需要的字段(但不使用sn-p中显示的序数)?

【问题讨论】:

  • 我自己对 TVP 和 Dapper 的实验说不。无论如何,用于传递数据的用户定义的表类型应该很简单——为什么你需要一个主键和标识列在你要从存储过程中复制数据的东西上?亲吻。

标签: c# sql-server dapper table-valued-parameters .net-standard-1.6


【解决方案1】:

看来我已经找到了答案——至少在这里如何忽略身份列:

SqlMetaData[] metaData =
{
    new SqlMetaData("IdentityColumn", SqlDbType.Int, true, false, SortOrder.Unspecified, -1),
    new SqlMetaData("Field1", SqlDbType.NVarChar, 256),
    new SqlMetaData("Field2", SqlDbType.Int),
};

foreach (var item in items)
{
    var record = new SqlDataRecord(metaData);
    record.SetValue(1, item.Field1); //starting from 1; 0 is for ident col
    record.SetValue(2, item.Field2);
    dataTable.Add(record);
}

希望这可以帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2014-08-29
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多