使用Dapper调用存储过程时,我收到以下错误:
Procedure or function has too many arguments specified
我使用DynamicParameters向查询添加简单参数列表。
参数代码如下所示:
var parameters = new DynamicParameters();
parameters.Add(p.Name, p.Value, direction: p.Mode);
查询代码如下所示:
var result = _connection.Query<T>(
string.Format("{0}.{1}", request.SchemaName, request.StoredProcedureName),
parameters,
commandType: CommandType.StoredProcedure,
transaction: _transaction);
探查器中执行的sql显示如下:
exec dbo.storedProcedureName @ParameterNames1=N'ParameterName',@ParameterNames2=N'ParameterName',@RemoveUnused=1
@ ParameterNames1根本不是如何调用参数的。实际上,名称是作为值传递的(N&#39; ParameterName&#39;)。 @RemoveUnused参数对我来说似乎是完全随机的,因为它根本不会出现在调用代码中。
可在此处找到完整代码:GitHub project,第61和228行。
编辑:我发现问题是由两次调用相同的过程引起的,结果集不同。所以我第一次用Query调用它,第二次用Query调用它。为什么Dapper在这种情况下遇到麻烦仍然是一个谜。
答案 0 :(得分:2)
我最近遇到过这个问题,这似乎是由以下原因引起的:
Query<T>()
代替QueryMultiple()
,然后映射数据集
通过Read<T>
。我们最近从旧版本的Dapper升级到v1.4以支持表变量参数,我们开始体验此行为是升级的直接结果。
<强>解决方案:强>
将基于Query<T>
的代码转换为QueryMultiple
实施。
答案 1 :(得分:1)
我根本无法重现这个:
public void SO25069578_DynamicParams_Procs()
{
var parameters = new DynamicParameters();
parameters.Add("foo", "bar");
try { connection.Execute("drop proc SO25069578"); } catch { }
connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]");
var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though
var row = connection.Query<HazX>("SO25069578", parameters,
commandType: CommandType.StoredProcedure, transaction: tran).Single();
tran.Rollback();
row.X.IsEqualTo("bar");
}
public class HazX
{
public string X { get; set; }
}
工作正常。 在RemoveUnused
上 DynamicParameters
属性,位:使用动态参数时,不应添加。我甚至尝试过使用基于模板的构造函数:
parameters = new DynamicParameters(parameters);
但又一次:这很好用。您是否有可能使用真正的,旧的版本的dapper?你用的是哪个版本?
答案 2 :(得分:0)
我意识到这是一个旧线程。但是,我使用的是Nuget软件包的最新版本(1.60.6),最近遇到了此问题。
要重现此内容,您将需要一个存储过程,该存储过程基于输入参数可以返回1或2(大于1)个结果集。在代码中,我也使用2种不同的扩展方法来调用它(QueryMultipleAsync
将该参数设置为1或true,QueryAsync
将其设置为0或false)。如果您的测试最终调用SP首先返回多个结果集,则随后需要1个结果集的调用将失败,并显示此错误。
我设法解决此问题的唯一方法是将SP分解为2,以便它们具有不同的名称。
作为参考,这是我所说的SP:
var data = await sqlConnection.QueryAsync<T>(
StoredProcedureName,
parms,
transaction: null,
commandTimeout: null,
commandType: CommandType.StoredProcedure)
和
var data = await sqlConnection.QueryMultipleAsync(
StoredProcedureName,
param: p,
commandType: CommandType.StoredProcedure)
.Map<Type1, Type2, long>
(
o1 => o1.Id,
o2 => o2.FkId ?? 0,
(o1, o2) => { o1.Children = o2.ToList(); }
);
答案 3 :(得分:0)
最近遇到了这个问题,因为使用不同的 Dapper 方法两次调用相同的过程。
第一次调用相同的 SQL 存储过程是通过 .QueryMultiple。使用 .QuerySingleOrDefault 再次使用参数调用相同的过程导致参数为原始问题中提到的 ParameterNames1 和 RemoveUnused。