我正在对已发布存储过程进行访问的现有SQL Server数据库使用OrmLite。其中一个SP需要3个int参数,但是期望一个或另一个为null。但是,没有任何参数被声明为可选参数。
这是我尝试过的代码:
using (IDbConnection scon = myFactory.OpenDbConnection())
{
rowCount = scon.SqlScalar<int>("EXEC myProc @FileID, @FileTypeID, @POID",
new
{
FileID = req.FileId,
FileTypeID = (int?)null,
POID = req.PoId,
});
}
但这会产生SqlException:必须声明标量变量“@FileTypeID”。检查封面下的SQLParameterCollection表明OrmLite只生成了两个参数。
是否可以使用空参数调用此SP?
答案 0 :(得分:2)
SqlScalar不支持它。当您查看代码时,您可以看到来自ServiceStack.OrmLite.OrmLiteReadExtensions类的SqlScalar方法执行SetParameters方法,负责将参数添加到查询中,第二个参数(excludeNulls)等于true我不知道为什么 - mythz应该回答这个 ;)。
如果你想修复它,那么你已经改变了所有的SqlScalar方法来调用SetParameters和true,而SetParameters方法应该如下所示(必须支持DBNull.Value不为null)
private static void SetParameters(this IDbCommand dbCmd, object anonType, bool excludeNulls)
{
dbCmd.Parameters.Clear();
lastQueryType = null;
if (anonType == null) return;
var pis = anonType.GetType().GetSerializableProperties();
foreach (var pi in pis)
{
var mi = pi.GetGetMethod();
if (mi == null) continue;
var value = mi.Invoke(anonType, new object[0]);
if (excludeNulls && value == null) continue;
var p = dbCmd.CreateParameter();
p.ParameterName = pi.Name;
p.DbType = OrmLiteConfig.DialectProvider.GetColumnDbType(pi.PropertyType);
p.Direction = ParameterDirection.Input;
p.Value = value ?? DBNull.Value; // I HAVE CHANGED THAT LINE ONLY
dbCmd.Parameters.Add(p);
}
}
更改代码后,您可以按以下方式为参数设置null:
var result = db.SqlScalar<int>("EXEC DummyScalar @Times", new { Times = (int?)null });
在我看来,你可以把它描述为github上的缺陷,我可以提出拉取请求。