从表值参数c#中检索数据

Posted

技术标签:

【中文标题】从表值参数c#中检索数据【英文标题】:Retrieving data from table value parameter c# 【发布时间】:2021-09-02 15:24:23 【问题描述】:

我以前没有使用过 TVP 或存储过程,我希望我能得到一些关于如何在 c# 中检索第一个查询的等效项作为数据集的说明。我创建了一个似乎可以工作的自定义类型和过程,每当我声明一个变量并在 SSMS 中执行存储过程时它就可以工作,我只是不确定如何在代码中复制它。

SELECT ServLoc.ID, Meters.MeterID, MeterHistory.Stuff
FROM ServLoc 
INNER JOIN Meters ON ServLoc.ID = Meters.ServLocID
INNER JOIN MeterHistory ON Meters.MeterID = MeterHistory.MeterID
WHERE ServLoc.ID IN (1,2,3...40,000)



CREATE TYPE dbo.ServLocMeters 
AS TABLE (ServLocID int NOT NULL)


CREATE PROCEDURE [dbo].[sp_ServLocMeters]
    @newServLocMeters ServLocMeters READONLY
AS
    SELECT ServLocID, Meters.MeterID, MeterHistory.Stuff
    FROM Meters 
    INNER JOIN MeterHistory ON Meters.MeterID = MeterHistory.MeterID
    WHERE ServLocID IN (SELECT ServLocID FROM @newServLocMeters)
    ORDER BY ServLocID


declare @table as ServlocMeters
insert into @table values (1)
insert into @table values (2)
insert into @table values (31)
exec sp_servlocmeters @table

【问题讨论】:

你读过TVPdocumentation吗?它有 C# 代码示例。 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀! 明白了,谢谢。是的,我已经查看了文档,但是我一直在努力寻找如何在 c# 中使用带有数据适配器的查询(链接也不正确)@DanGuzman 对不起,我的意思是这个链接:docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/… 如果您的表类型有一个主键CREATE TYPE dbo.ServLocMeters AS TABLE (ServLocID int PRIMARY KEY);,您可能会获得更好的性能 【参考方案1】:

不久之后我发现了一个例子,哈哈。感谢 marc 的前缀提醒。

DataTable table = new DataTable("ServLoc");
table.Columns.Add("ServLocID", typeof(int));
for (int i = 0; i < 3000; i++)

    table.Rows.Add(1 + i);


DataSet dbDatasets = new DataSet();
using (SqlConnection conn = new SqlConnection(connectionString))

    SqlCommand cmd = new SqlCommand("sp_ServLocMeters", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter sqlParam = cmd.Parameters.AddWithValue("@newServLocMeters", table);
    cmd.CommandTimeout = 0;
    sqlParam.SqlDbType = SqlDbType.Structured; //tells ADO.NET we are passing TVP  
    SqlDataAdapter adapter = new SqlDataAdapter(cmd);

    adapter.Fill(dbDatasets);

【讨论】:

您需要指定表类型名称,也就是ParameterDirection。最好添加这样的参数cmd.Parameters.Add(new SqlParameter("@newServLocMeters", SqlDbType.Structured) TypeName = "dbo.ServLocMeters", Direction = ParameterDirection.Input, Value = table);您还需要使用using处理您的适配器

以上是关于从表值参数c#中检索数据的主要内容,如果未能解决你的问题,请参考以下文章

从表值函数中选择?

如何使用 C# 和 SQL 将表值参数传递给用户定义的数据表

如何检索 sql server 内联表值函数的返回值的元数据?

EF:从 C# 将表值参数传递给用户定义的函数

从表值函数返回表并在临时表中设置该值

从表值函数返回显式 Open XML 结果集