2013-07-02 24 views
3

我对已发布存储过程进行访问的现有SQL Server数据库使用OrmLite。其中一个SP需要3个int参数,但期望其中一个会为空。但是,没有任何参数被声明为可选。如何使用OrmLite将非可选的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

我也试过使用DBNull.Value作为参数,没有运气。 – AndrewCr

回答

2

它不受SqlScalar支持。当你看代码时,你可以看到ServiceStack.OrmLite.OrmLiteReadExtensions类中的SqlScalar方法执行SetParameters方法负责添加参数,以便用第二个参数(excludeNulls)等于true查询。我不知道为什么 - mythz应该为此回答; )。
如果你要修复它,那么你必须改变所有SqlScalar方法来调用与真实SetParameters方法SetParameters应该看起来像下面当您更改代码,那么你(必须支持DBNull.Value NOT 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); 
     } 
    } 

可以通过以下方式设置参数无效:

var result = db.SqlScalar<int>("EXEC DummyScalar @Times", new { Times = (int?)null }); 

在我看来,你可以把它描述为在GitHub上的缺陷,我可以拉请求。

+0

好的,我已经将它添加到github作为问题#274。 (https://github.com/ServiceStack/ServiceStack.OrmLite/issues/274)感谢您的回复 - 抱歉,我很迟缓地回复您。我错过了SO的通知。 – AndrewCr

相关问题