如何在.NET中提取SQL Server可空输出参数的底层系统类型?
在.NET中提取SQL Server可空输出参数的底层系统类型
我正在尝试在.NET中提取SQL Server可空输出参数的底层系统类型(即使参数值为NULL)。这类参数类型的FullName示例如下:
FullName = "System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]&"}
使用Nullable.GetUnderlyingType(pinfo.parameterType)时,仅针对输出参数会返回null。我想找到一种正规方法替代当前的字符串处理方式,目前的代码如下:
if (pi != null) { t = Nullable.GetUnderlyingType(pi.ParameterType) ?? pi.ParameterType; isOut = pi.IsOut; } if (isOut) { //output vars do weird 5#1T with types //FullName = "System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]&"} // so we to get the underlying type by this kludge for now. // need a better way in future // if (t.Name == "Nullable`1&") { int pos1 = t.FullName.IndexOf("[[") + 2; int pos2 = t.FullName.IndexOf(",", pos1 + 1); string tname = t.FullName.Substring(pos1, pos2 - pos1); t = System.Type.GetType(tname); } }
用于测试的SQL存储过程如下:
ALTER PROCEDURE [dbo].[spTestOutputVariableHandling] -- Add the parameters for the stored procedure here @ErrorSeverity INT, @ErrorState INT, @idVar UNIQUEIDENTIFIER OUTPUT , @boolVar BIT OUTPUT, @stringVar NVARCHAR(255) OUTPUT, @intVar INT OUTPUT, @decVar DECIMAL(18,2) OUTPUT, @singleVar REAL OUTPUT, @doubleVar FLOAT OUTPUT, @dateVar DATETIME2 OUTPUT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from SET @idVar= NEWID() SET @boolVar = 1 SET @stringVar = 'Test String' Set @intVar = 1000 SET @decVar = 234.67 SET @singleVar = 7474747.587598 SET @doubleVar = 8876543212345.98767 SET @dateVar = GETDATE() SELECT TOP 1 * FROM Things IF (@ErrorSeverity > 0) BEGIN DECLARE @erMsg NVARCHAR(MAX) Set @erMsg = 'Test Error Severity:'+STR(@ErrorSeverity,3,0)+'State: '+STR(@ErrorState,3,0) RAISERROR(@erMSg,@ErrorSeverity, @ErrorState) WITH LOG END END
正规解决方案
问题根源在于输出参数的类型是引用类型(ByRef),对应示例中的&标记,直接用Nullable.GetUnderlyingType无法处理这种类型。需要先获取引用类型指向的实际元素类型,再提取底层类型。
修改后的代码如下:
if (pi != null) { isOut = pi.IsOut; Type parameterType = pi.ParameterType; // 处理输出参数的引用类型,提取实际元素类型 if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); } // 正常提取可空类型的底层类型 t = Nullable.GetUnderlyingType(parameterType) ?? parameterType; }
关键逻辑说明
IsByRef:判断当前类型是否为引用类型(对应输出参数的&标记)GetElementType():获取引用类型指向的实际元素,比如Nullable<int>&会被转换为Nullable<int>- 后续调用
Nullable.GetUnderlyingType即可正确提取出底层的int类型,完全替代不可靠的字符串解析逻辑
内容的提问来源于stack exchange,提问作者Matthew Hudson
相关产品推荐
相关产品推荐

