How to pass non-optional NULL parameters to a Stored Proc using OrmLite

浪子不回头ぞ 提交于 2019-12-10 10:28:24

问题


I'm using OrmLite against an existing SQL Server database that has published stored procedures for access. One of these SPs takes 3 int parameters, but expects that one or another will be null. However, none of the parameters are declared optional.

Here's the code I've tried:

        using (IDbConnection scon = myFactory.OpenDbConnection())
        {
            rowCount = scon.SqlScalar<int>("EXEC myProc @FileID, @FileTypeID, @POID",
            new
            {
                FileID = req.FileId,
                FileTypeID = (int?)null,
                POID = req.PoId,
            });
        }

But this produces a SqlException: Must declare the scalar variable "@FileTypeID". Examining the SQLParameterCollection under the covers shows that only two parameters are being generated by OrmLite.

Is it possible to call this SP with a null parameter?


回答1:


It's not supported with SqlScalar. When you look at the code then you can see that SqlScalar methods from class ServiceStack.OrmLite.OrmLiteReadExtensions execute SetParameters method responsible for adding parameters to query with second parameter(excludeNulls) equal true I don't know why- mythz should answer for this ;).
If you want to fix it then you have change all SqlScalar methods to invoke SetParameters with true and SetParameters method should look like following(must support 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);
        }
    }

When you change code then you can set null for parameters in the following way:

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

In my opinion you can describe it as a defect on github and I can make pull request.



来源:https://stackoverflow.com/questions/17432909/how-to-pass-non-optional-null-parameters-to-a-stored-proc-using-ormlite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!