Dapper 存储过程在将 IEnumerable 传递给它时指定了太多参数
Dapper stored procedure has too many arguments specified when passing IEnumerable to it
我正在通过这种方法调用我的程序:
public async Task<IEnumerable<Algorithm>> GetAlgorithmsByNameAsync(IEnumerable<string> names)
{
var parameters = new DynamicParameters();
parameters.Add("@names", names);
var connection = _connection.GetOpenConnection();
return await connection.QueryAsync<Algorithm>("GetAlgorithmsByName", parameters, commandType: CommandType.StoredProcedure);
}
我的程序是这样的:
CREATE TYPE [dbo].[StringList] AS TABLE(
[Item] [NVARCHAR](MAX) NULL
);
--PROCEDURE HERE--
CREATE PROCEDURE GetAlgorithmsByName
@names StringList READONLY -- my own type
AS
BEGIN
SELECT ALgorithmId, Name From Algorithms WHERE Name IN (SELECT Item FROM @names)
END
从上面的代码中,我得到一个错误:
"Procedure or function GetAlgorithmsByName has too many arguments specified."
我做错了什么?如何使用 dapper 将 IEnumerable<string>
传递给存储过程?
在您的存储过程中期望 [Item] [NVARCHAR](MAX)
,这意味着一项而您正在传递 IEnumerable<string> names
。这就是您收到错误的原因。
有很多方法可以将字符串列表传递给 sp
- XML
- 像
CREATE TYPE NameList AS TABLE ( Name Varchar(100) );
一样使用table-valued parameters
- 使用
names = "Name1, Name2, .. , Namen";
然后sql你可以使用T-SQL split string得到名字列表
已更新
你传递的参数不正确,我们通过这种方式修复它
using (var table = new DataTable())
{
table.Columns.Add("Item", typeof(string));
for (int i = 0; i < names.length; i++)
table.Rows.Add(i.ToString());
var pList = new SqlParameter("@names", SqlDbType.Structured);
pList.TypeName = "dbo.StringList";
pList.Value = table;
parameters.Add(pList);
}
Table 有价值的参数使用起来并不简单;一种方法是通过 Dapper 在 DataTable
上添加的扩展方法(类似于 AsTableValuedParameter
),但是:它不像 IEnumerable<T>
那样简单地工作——至少,今天不是。你也可能不需要 DynamicParameters
这里。
如果你想要的只是一组字符串,那么一个非常实用的选择是查看 SQL 服务器中的内置 string_split
API,如果你可以定义一个数据中从未使用过的分隔符标记。然后你可以只传递一个分隔字符串。
您可以使用 IEnumerable(动态)而不是 IEnumerable(字符串)。
检查此 link 并尝试
我正在通过这种方法调用我的程序:
public async Task<IEnumerable<Algorithm>> GetAlgorithmsByNameAsync(IEnumerable<string> names)
{
var parameters = new DynamicParameters();
parameters.Add("@names", names);
var connection = _connection.GetOpenConnection();
return await connection.QueryAsync<Algorithm>("GetAlgorithmsByName", parameters, commandType: CommandType.StoredProcedure);
}
我的程序是这样的:
CREATE TYPE [dbo].[StringList] AS TABLE(
[Item] [NVARCHAR](MAX) NULL
);
--PROCEDURE HERE--
CREATE PROCEDURE GetAlgorithmsByName
@names StringList READONLY -- my own type
AS
BEGIN
SELECT ALgorithmId, Name From Algorithms WHERE Name IN (SELECT Item FROM @names)
END
从上面的代码中,我得到一个错误:
"Procedure or function GetAlgorithmsByName has too many arguments specified."
我做错了什么?如何使用 dapper 将 IEnumerable<string>
传递给存储过程?
在您的存储过程中期望 [Item] [NVARCHAR](MAX)
,这意味着一项而您正在传递 IEnumerable<string> names
。这就是您收到错误的原因。
有很多方法可以将字符串列表传递给 sp
- XML
- 像
CREATE TYPE NameList AS TABLE ( Name Varchar(100) );
一样使用table-valued parameters
- 使用
names = "Name1, Name2, .. , Namen";
然后sql你可以使用T-SQL split string得到名字列表
已更新 你传递的参数不正确,我们通过这种方式修复它
using (var table = new DataTable())
{
table.Columns.Add("Item", typeof(string));
for (int i = 0; i < names.length; i++)
table.Rows.Add(i.ToString());
var pList = new SqlParameter("@names", SqlDbType.Structured);
pList.TypeName = "dbo.StringList";
pList.Value = table;
parameters.Add(pList);
}
Table 有价值的参数使用起来并不简单;一种方法是通过 Dapper 在 DataTable
上添加的扩展方法(类似于 AsTableValuedParameter
),但是:它不像 IEnumerable<T>
那样简单地工作——至少,今天不是。你也可能不需要 DynamicParameters
这里。
如果你想要的只是一组字符串,那么一个非常实用的选择是查看 SQL 服务器中的内置 string_split
API,如果你可以定义一个数据中从未使用过的分隔符标记。然后你可以只传递一个分隔字符串。
您可以使用 IEnumerable(动态)而不是 IEnumerable(字符串)。
检查此 link 并尝试