首页 > 解决方案 > Dapper / SQL Server:仅将 TVP 传递给具有所需字段的存储过程

问题描述

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

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 列。

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

标签: c#sql-serverdappertable-valued-parameters.net-standard-1.6

解决方案


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

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);
}

希望这可以帮助别人。


推荐阅读