【问题标题】:DataTable convert field value to TDataTable 将字段值转换为 T
【发布时间】:2012-09-04 11:28:00
【问题描述】:

我有以下功能:

public T GetScalar<T>(string sql, T defaultValue, SQLParam[] sqlParams = null)
{
    DataTable dt = GetDataTable(sql, sqlParams);
    if (dt.Rows.Count == 0) return defaultValue;
    else
    {
        try
        {
            object tmp = dt.Rows[0][0];
            return (T)tmp;
        }
        catch { return defaultValue; }
    }
}

我收到了InvalidCastException。

在调试过程中,我可以看到tmp 的值为3,而T 的类型为int。

这里有什么问题?

编辑

一点背景知识:这曾经在 MySQL 中工作。我现在已经转移到 SQLServer(谢天谢地几乎没有努力),但现在这段代码失败了。

【问题讨论】:

  • 为什么首先要声明对象?为什么不只是T tmp?
  • 如果你只想要一个标量,你为什么要首先加载到DataTable? (这纯粹是出于好奇)
  • @Joel - 我只是将 tmp 放在那里进行调试,最初是 return (T)dt.Rows[0][0]
  • 也许您还想使用Field 方法访问数据行。
  • 这很奇怪——这曾经在 MySQL 中工作(使用完全相同的代码)——但现在由于其他原因我需要迁移到 SQLServer。这段代码现在中断了。

标签: c# .net generics casting


【解决方案1】:

尝试换行:

return (T)tmp;

到

return (T) Convert.ChangeType(tmp, typeof(T));

【讨论】:

    【解决方案2】:

    我怀疑这个值实际上是long,或者类似的东西 - 当你拆箱时,你必须拆箱到 exact 类型(有关于签名和枚举的一些奇怪之处,但不是long vs int)。

    如果您关注tmp.GetType(),您应该能够看到这一点 - 或者只是从 SQL 中确定它应该是什么类型。

    【讨论】:

    • @MarcGravell: 在方向盘上睡着了 :(
    • 手表刚刚显示它的类型为object {int}。数据库类型也是 int。很困惑为什么它不起作用,但 Michal 的解决方案现在有效
    • @Simon:你真的打电话给GetType() 吗?如果您确实有一个 int 并且无法转换为它,那将是非常奇怪的......
    • 这是我得到的:Type t2 = tmp.GetType() = t2 {Name = "Int32", FullName = "System.Int32"}
    • @Simon:还有typeof(T)?你能制作一个简短但完整的程序来证明这一点吗?我很难相信你已经设法打破拆箱......
    【解决方案3】:

    尝试将try 块中的代码更改为:

            T tmp = dt.Rows[0].Field<T>(0);
            return tmp;
    

    看看这是否有效 - 或者至少会给你一个更好的错误。 :-)

    【讨论】:

      猜你喜欢
      • 2011-01-17
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多