我使用SQL Server 2012和Entity Framework6。
我创建了表值参数:
CREATE TYPE IdArray AS TABLE
(
Id int
);
这是我的存储过程:
ALTER PROCEDURE [dbo].[SP_TEST_TLP]
@List dbo.IdArray READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM Clients
WHERE Clients.Id IN (select Id from @List)
END
从Visual Studio中我调用存储过程并将参数传递给存储过程。
我是这样做的:
创建DataTable:
var myDataTable = new DataTable();
myDataTable.Columns.Add("Id", typeof(int));
myDataTable.Rows.Add(1);
myDataTable.Rows.Add(3);
myDataTable.Rows.Add(6);
从DataTable创建SqlParameter
:
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@List";
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "dbo.IdArray";
parameter.Value = myDataTable;
Fire存储过程和传递参数:
var data = _context.Database.ExecuteSqlCommand("SP_TEST_TLP @List", parameter);
问题是ExecuteSqlCommand
会返回-1
。
为什么ExecuteSqlCommand
会在我预期来自数据库的行时返回-1
?
更新
更改此行:WHERE Clients.Id IN(' @ List')
对此:WHERE Clients.Id IN(从@List中选择Id)
答案 0 :(得分:4)
ExecuteSqlCommand返回一个int,用于操作查询(Insert,Update)并返回受单个非查询影响的行数。 尝试使用ExecuteDataTable或类似结果。
这是一个很好的例子: Retrieve a DataTable using a SQL Statement
答案 1 :(得分:3)
是的,这是ADO.Net,但这是底层代码。
对于UPDATE,INSERT和DELETE语句,返回值为 受命令影响的行数。当a上存在触发器时 正在插入或更新的表,返回值包括数字 受插入或更新操作影响的行数和数字 受触发器或触发器影响的行数。对于所有其他类型的 语句,返回值为-1。如果发生回滚,则返回 值也是-1。
BTW ......你的存储过程中有一个错误。
CREATE PROCEDURE [dbo].[USP_TEST_TLP] -- don't use SP_
@List dbo.IdArray READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM Clients
WHERE Clients.Id IN (SELECT Id FROM @list) -- use subquery
/* or a join
SELECT *
FROM Clients
INNER JOIN @list I ON Clients.Id = I.Id
*/
END