c# - 如何传递表值参数

标签 c# .net ado.net

我正在尝试将表值参数传递给存储过程,但我一直收到异常(见下文)。

SqlCommand c = new SqlCommand("getPermittedUsers", myConn) { CommandType = CommandType.StoredProcedure };

c.Parameters.AddWithValue("@intNotifyingUserId", notifyingUserId);
c.Parameters.AddWithValue("@tSelectedPdfIds", sharedPdfs).SqlDbType = SqlDbType.Structured;

SqlDataReader dr = c.ExecuteReader();

类型在服务器上定义如下:

CREATE TYPE [dbo].[IdList] AS TABLE(
    [Id] [int] NOT NULL
)

我尝试将 sharedPdfs 作为 List<int> 传递, 和 IQueryable<int> ,但不断收到以下异常:

Object must implement IConvertible.

有人知道我做错了什么吗?文档暗示我应该能够将列表作为 TVP 传递,但没有提供任何示例。

谢谢。

最佳答案

以下示例说明了使用 DataTableIEnumerable<SqlDataRecord> :

SQL 代码

CREATE TABLE dbo.PageView
(
    PageViewID BIGINT NOT NULL CONSTRAINT pkPageView PRIMARY KEY CLUSTERED,
    PageViewCount BIGINT NOT NULL
);
CREATE TYPE dbo.PageViewTableType AS TABLE
(
    PageViewID BIGINT NOT NULL
);
CREATE PROCEDURE dbo.procMergePageView
    @Display dbo.PageViewTableType READONLY
AS
BEGIN
    MERGE INTO dbo.PageView AS T
    USING @Display AS S
    ON T.PageViewID = S.PageViewID
    WHEN MATCHED THEN UPDATE SET T.PageViewCount = T.PageViewCount + 1
    WHEN NOT MATCHED THEN INSERT VALUES(S.PageViewID, 1);
END

C#代码

private static void ExecuteProcedure(bool useDataTable, string connectionString, IEnumerable<long> ids) {
    using (SqlConnection connection = new SqlConnection(connectionString)) {
        connection.Open();
        using (SqlCommand command = connection.CreateCommand()) {
            command.CommandText = "dbo.procMergePageView";
            command.CommandType = CommandType.StoredProcedure;

            SqlParameter parameter;
            if (useDataTable) {
                parameter = command.Parameters.AddWithValue("@Display", CreateDataTable(ids));
            }
            else {
                parameter = command.Parameters.AddWithValue("@Display", CreateSqlDataRecords(ids));
            }
            parameter.SqlDbType = SqlDbType.Structured;
            parameter.TypeName = "dbo.PageViewTableType";

            command.ExecuteNonQuery();
        }
    }
}

private static DataTable CreateDataTable(IEnumerable<long> ids) {
    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(long));
    foreach (long id in ids) {
        table.Rows.Add(id);
    }
    return table;
}

private static IEnumerable<SqlDataRecord> CreateSqlDataRecords(IEnumerable<long> ids) {
    SqlMetaData[] metaData = new SqlMetaData[1];
    metaData[0] = new SqlMetaData("ID", SqlDbType.BigInt);
    SqlDataRecord record = new SqlDataRecord(metaData);
    foreach (long id in ids) {
        record.SetInt64(0, id);
        yield return record;
    }
}

关于c# - 如何传递表值参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6989560/

相关文章:

.net - 如何确定给定的整数是否在特定的枚举中?

asp.net - 获取DataPager当前页码

c# - 转义 sql 字符串的简单方法?

c# - 在 C# 中将 SqlDataReader 列值转换为 json 字符串

c# - WPF:图像上未显示添加的行

c# - 使用从软件应用程序保存/另存为将文件上传到网站

c# - dapper插入/更新需要内联sql吗?

JavaScript 在部分 View MVC 中失败

c# - 更改禁用组合框的前景色

sql - 带时区的 Oracle DateTime 查询