通过entity framework将int数组传递给T-SQL存储过程

我阅读了很多post并认为我理解了这些概念,但是我的一小部分内容未能从C#/ EF模块传递到SQL Server存储过程。 希望其他人可以发现问题所在。

我正在使用EF6,4.5 .Net Framework,SQL Server 2014

在数据库中我创建了这些类型/过程:

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

请注意,名为“Person”的表存在列’Id’(int)和’LastName’(nvarchar),并且具有数据。

 CREATE PROCEDURE [dbo].[GetUsers] @UserIds dbo.IntsTTV READONLY AS BEGIN SELECT p.LastName FROM [dbo].[Person] p INNER JOIN @UserIds ids On p.Id = ids.Id; END 

// C#代码

 SqlMetaData[] columns = new SqlMetaData[1]; columns[0] = new SqlMetaData("Id", SqlDbType.Int); SqlDataRecord row = new SqlDataRecord(columns); row.SetInt32(0, 1); // Id of '1' is valid for the Person table SqlDataRecord[] table = new SqlDataRecord[1]; table[0] = row; SqlParameter parameter = new SqlParameter(); parameter.SqlDbType = SqlDbType.Structured; parameter.ParameterName = "@UserIds"; parameter.TypeName = "dbo.IntsTTV"; parameter.Direction = ParameterDirection.Input; parameter.Value = table; SqlParameter[] parameters = new SqlParameter[1]; parameters[0] = parameter; var res = _db.Database.SqlQuery("GetUsers", parameters).ToList(); 

代码确实成功调用了proc,如果我硬编码proc只是返回一个LastName的选择,那么C#代码就会收到它。 这告诉我什么起作用。

如果我从其他T-SQL代码调用proc,传入一个准备好的表值参数(IntsTTV)的int,它就可以了。

在proc中,如果我选择传递的参数表的行数,则在从C#代码调用时得到零,但是从T-SQL代码调用时得到正确的计数。

我错过了什么?

这就是我用表值参数调用存储过程的方法。 主要区别在于我使用DataTable参数。

我记得有参数名称绑定的问题,但我不记得他们究竟是什么。 这解释了我在过程调用的语法中所做的更改。 我知道这个应该有效。

 var dataTable = new DataTable(); dataTable.TableName = "dbo.IntsTTV"; dataTable.Columns.Add("Id", typeof(int)); dataTable.Rows.Add(1); // Id of '1' is valid for the Person table SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured); parameter.TypeName = dataTable.TableName; parameter.Value = dataTable; var res = _db.Database.SqlQuery("EXEC GetUsers @UserIds", parameter).ToList(); 

那很有效! 为了别人的缘故,我会在这里发布精确的代码,我不得不稍微调整一下。

 var dataTable = new DataTable(); dataTable.TableName = "dbo.IntsTTV"; dataTable.Columns.Add("Id", typeof(int)); dataTable.Rows.Add(1); // Id of '1' is valid for the Person table SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured); parameter.TypeName = "dbo.IntsTTV"; parameter.Value = dataTable; var res = _db.Database.SqlQuery("EXEC dbo.GetUsers @UserIds", parameter).ToList(); 

我知道已经找到了一种可以帮助其他人的不同方式

STRING_SPLIT

 declare @intArray nvarchar(1000) set @intArray = '1,2,3,4,5' select value from STRING_SPLIT(@intArray , ',') 

这将返回一个包含@intArray中数字的新表

然后你只需要将它用作普通表

 select * from myMainTable where Id in (select value from STRING_SPLIT(@intArray , ','))