2010-02-22 98 views
1

我有一个存储过程。其输入参数之一是期待char(8)。我尝试将字符串“AAA”转换为这个特定的参数类型,这是一个DBType.AnsiStringFixedLength。C#:将字符串转换为DBType.AnsiStringFixedLength

object v = Convert.ChangeType("AAA", param.DbType.GetTypeCode()); 
// param is AnsiStringFixedLength 

但是,我得到的只是一个例外:输入字符串的格式不正确。 而堆栈跟踪说:在System.Number.StringToNumber(字符串str的NumberStyles选项,NumberBuffer &数的NumberFormatInfo信息,布尔parseDecimal)[...]

为什么System.Convert试图将一个字符串转换成一个数字,即使prodecure的参数期望char(8)?我该如何解决这个问题?我不想用一个巨大的开关情况,映射所有SQL类型CLR类型...

编辑: 这是有问题的代码:(A泛型方法调用任何MS SQL存储过程)

using (SqlConnection conn = new SqlConnection(this.config.ConnectionString)) 
{ 
    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.CommandText = this.config.StoredProcedureName; 

     conn.Open(); 
     SqlCommandBuilder.DeriveParameters(cmd); 

     foreach (SqlParameter param in cmd.Parameters) 
     { 
      if (param.Direction == ParameterDirection.Input || 
       param.Direction == ParameterDirection.InputOutput) 
      { 
       try 
       { 
        string rawParam = param.ParameterName.Replace("@", ""); 
        if (this.config.Parameters.ContainsKey(rawParam)) 
        { 
         try 
         { 
          param.Value = Convert.ChangeType(this.config.Parameters[rawParam], 
           param.DbType.GetTypeCode()); 
         } 
         catch(Exception oops) 
         { 
          throw new Exception(string.Format("Could not convert to '{0}'.", param.DbType), oops); 
         } 
        } 
        else 
         throw new ArgumentException("parameter's not available"); 
       } 
       catch (Exception e) 
       { 
        throw; 
       } 
      } 
     } 
     cmd.ExecuteNonQuery(); 
    } 
} 

实际参数值由this.config.Parameters提供 - 它们都是字符串。我遍历SqlCommand的参数列表并相应地设置它们。在这里需要将字符串值转换为参数的Sql类型,并且据我所知,Sql类型由param.DBType提供。

回答

2

你似乎混淆了一些东西,或者我没有得到你想要做的事情。 DbType(枚举)继承Enum并实现IConvertible - >您可以拨打GetTypeCode()。但是 - 你现在调用Enum.GetTypeCode(),它返回底层类型。如果您没有指定它(并且DbType没有),则任何Enum都支持int

你想用代码解决什么问题?为什么想要更改字符串的类型,如果参数是一个字符串(尽管具有固定长度)?


再看看这个问题,看起来更奇怪。你有一个对象v(可能是为了价值?) - 你对这个类型有什么关心?

object v1 = "Foo";

object v1 = 42;

是什么,你有什么区别?我想你想把值传递给别的东西,但是 - 如果你只是将值作为object来引用,你可能仍然需要将其转换。

请更新您的问题并解释您真正想要做什么,您期望获得什么。


关于评论:

我使用Convert.ChangeType(对象 值,类型码TYPECODE),所以它不是真的 转换成枚举/ INT。在 至少这是我以为......

见上文:DbType.GetTypeCode()是不是你想要的。尝试一下,给我一个怀疑的好处:你期待从DbType.AnsiStringFixedLength.GetTypeCode()得到什么?如果你尝试它,实际的结果是什么?

我们您的代码:您尝试将SqlParameter.Value属性设置为“正确”的类型。两件事:根据文档,你可能想要设置SqlParameter.SqlValue,这是根据文档使用SQL类型的值。另一方面,SqlParameter.Value是使用CLR类型的值,并允许推断DbType和SqlValue。旁注,实现细节:SqlParameter.SqlValue二传手只是调用的SqlParameter.Value再次二传手...

我会想到的是,ADO.NET的东西转换自身的价值,如果在所有可能的。如果没有跳过这个篮圈,你会得到什么错误?

+0

我正在使用Convert.ChangeType(对象值,TypeCode typeCode),所以它并不真正转换为Enum/int。至少这就是我认为的...... – user264833 2010-02-22 15:13:50

+0

没有。我无法相信它。我甚至没有尝试。它在没有改变类型的情况下工作得很好。我刚刚从这个内存很久以前,当我有麻烦的设置SqlCommand参数,而没有将对象转换为适当的SQL类型... 在任何情况下,非常感谢!我将使用SqlParameter.SqlValue。我知道,下一次,我会RTFM的;-) 编辑:对不起,我不能投票给你的答案,没有足够的声望点:D – user264833 2010-02-22 16:27:18