通过实体框架将int数组传递给T-SQL存储过程

时间:2017-10-12 12:53:00

标签: c# sql-server entity-framework stored-procedures

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

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

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

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<string>("GetUsers", parameters).ToList();

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

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

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

我错过了什么?

3 个答案:

答案 0 :(得分:5)

这就是我用表值参数调用存储过程的方法。主要区别在于我使用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<string>("EXEC GetUsers @UserIds", parameter).ToList();

答案 1 :(得分:3)

我知道这可以通过找到一种可能有助于其他人的不同方式来回答

STRING_SPLIT

int

这将返回一个包含@intArray

中数字的新表

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

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

答案 2 :(得分:0)

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

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<string>("EXEC dbo.GetUsers @UserIds", parameter).ToList();