在不使用 (Table-Valued-Parameter) 类型的情况下将集合作为 SQL 参数添加到 SqlCommand

Add collection as SQL parameter to SqlCommand without using (Table-Valued-Parameter) type

我试图在我的 SQL 查询中使用 table 作为参数,但如果不使用现有类型的名称(Table值参数)。

在 MSSQL 我可以这样做:

declare @mytable table (column1 int, column2 nvarchar(10))
insert into @mytable select 1, "test" UNION ALL select 2, "test2" UNION ALL [...]

select * from sometable inner join @mytable on sometable.id = @mytable.column1

要在 C# 中完成此操作,我可以(大致)执行以下操作:

SqlCommand cmd ...
var p = cmd.CreateParameter();
p.TypeName = "MyType";                  // <-- I dont't want to do this
p.SqlDbType = SqlDbType.Structured;
p.Value = myDataTable;
p.ParameterName = "table";
cmd.Parameters.Add(p);
cmd.CommandText = "select * from sometable inner join @mytable on ... ";

为此,我必须在数据库中创建类型 "MyType":CREATE TYPE [MyType] AS TABLE (...);

我的问题是我需要明确指定 table 的类型,即使在 MSSQL 中我可以内联完成(参见前面的示例)。其次,我需要在数据库中为每种可能的集合类型显式定义类型。

有什么方法可以将集合作为参数添加到 SQL 命令,而无需在数据库中声明其类型并将该类型用作参数的类型名称?

我最终使用了 Json(由@DanGuzman 提议),对其进行了测试,并且它在一个包含大约 500 个项目的相对简单的数据集(我的用例)中表现得非常好。

C#中的简单实现示例:

var col = new object[] { new { Column1 = "Test", Column2 = 1 }, new { Column1 = "2nd row", Column2 = 2 }, ... };
IDbDataParameter p = command.CreateParameter();
p.DbType = DbType.String;
p.ParameterName = "mytable";
p.Value = JsonConvert.SerializeObject(col); // NewtonSoft 
command.Parameters.Add(p);
command.CommandText = "SELECT * FROM OPENJSON(@mytable) WITH (Column1 nvarchar(max), Column2 int)";

参考文献: