[英]Strongly typed dataset as user defined table type parameter
我有一个存储过程来处理插入,更新和删除到定义为的表
CREATE TABLE [dbo].[TestTable](
[Id] [int] PRIMARY KEY NOT NULL,
[Data] [nvarchar](50) NOT NULL,
[ChangeDate] [datetime] NULL)
与存储的prodedure
CREATE PROCEDURE MergeTest
@Testing TestTableType readonly
AS
BEGIN
MERGE INTO Testing as Target
USING (SELECT * FROM @Testing) AS SOURCE
ON (Target.Id = Source.Id)
WHEN MATCHED THEN
UPDATE SET
Target.Data = Source.Data,
Target.ChangeDate = Source.ChangeDate
WHEN NOT MATCHED BY TARGET THEN
INSERT (Data, ChangeDate)
VALUES (Source.Data, Source.ChangeDate)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
RETURN 0;
END
和UDT类型为
CREATE TYPE TestTableType AS TABLE(
[Id] [int] PRIMARY KEY NOT NULL,
[Data] [nvarchar](50) NOT NULL,
[ChangeDate] [datetime] NULL)
我正在尝试使用此结构从C#执行批量插入等。 使用以下代码:
using (SqlConnection connection = new SqlConnection(@"..."))
{
connection.Open();
DataTable DT = new DataTable();
DT.Columns.Add("Id", typeof(int));
DT.Columns.Add("Data", typeof(string));
DT.Columns.Add("ChangeDate", typeof(DateTime));
for (int i = 0; i < 100000; i++)
{
DT.AddTestRow((i + 1), (i + 1).ToString(), DateTime.Now);
}
using (SqlCommand command = new SqlCommand("MergeTest", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@Testing", DT);
command.ExecuteNonQuery();
}
}
但是,当我改变线条
DataTable DT = new DataTable();
DT.Columns.Add("Id", typeof(int));
DT.Columns.Add("Data", typeof(string));
DT.Columns.Add("ChangeDate", typeof(DateTime));
至
DataSet1.TestDataTable DT = new DataSet1.TestDataTable();
这是同一个DataTable
结构的强类型版本我得到了一个Argument Exception
错误
从对象类型TestBulkInsertDataset.DataSet1 + TestDataTable到已知的托管提供程序本机类型不存在映射。
有没有办法使用强类型DataTable
作为用户定义的表类型参数?
找到了答案。 使用强类型数据表时,必须指定参数的类型。 参数行变为:
var testingparam = command.Parameters.AddWithValue("@Testing", DT);
testingparam.SqlDbType = SqlDbType.Structured;
然后一切正常。
你尝试过这样的事吗?
DataSet1.TestDataTable DT = new DataSet1.TestDataTable();
// Fill data table
DataTable DT1 = DT; // DataSet1.TestDataTable should be a subclass of DataTable
using (SqlCommand command = new SqlCommand("MergeTest", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@Testing", DT1);
command.ExecuteNonQuery();
}
如果键入的DataSet仍然是常规DataSet和DataTables的子类,我认为这样可行。
ETA:既然这不起作用,那怎么样?
DataSet DS1 = new DataSet();
DS1.Merge(DT, false, MissingSchemaAction.Add);
// etc.
command.Parameters.AddWithValue("@Testing", DS1.Tables[0]);
假设有效(并且您可能不得不使用Merge方法的重载来获得所需的结果),您将在DataSet中获得一个DataTable,它具有DT的架构和数据,即DataSet1.TestDataTable
,但它只是输入DataTable
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.