【问题标题】:How to get Guid from SqlDataReader uniqueidentifier如何从 SqlDataReader uniqueidentifier 获取 Guid
【发布时间】:2013-07-18 22:40:20
【问题描述】:

SQL Server 2008(版本 10.50.2550)。

我有一个选择查询来返回唯一标识符类型的单列。

我想把它放到一个 Guid 类型的 C# 变量中。

以下所有方法都会导致异常。

阅读器的类型为 SqlDataReader。

using (var reader = command.ExecuteReader())
{

    if (reader.Read())
    {       
        Guid guid = reader.GetGuid(reader.GetOrdinal("integ_schemehistoryId")); //1

        Guid guid = Guid.Parse((string)reader["integ_schemehistoryId"]); //2

        Guid guid = (Guid)reader["integ_schemehistoryId"]; //3

        Guid guid = new Guid((string)reader["integ_schemehistoryId"]); //4

        Guid guid = Guid.Parse(reader["integ_schemehistoryId"].ToString()); //5
    }

}

1 的错误:

System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting from a character string to uniqueidentifier.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.HasMoreRows()
   at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

2 错误:

System.InvalidCastException: Unable to cast object of type 'System.Guid' to type 'System.String'.
   at Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

3 的错误:

System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting from a character string to uniqueidentifier.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.HasMoreRows()
   at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

4 错误:

System.InvalidCastException: Unable to cast object of type 'System.Guid' to type 'System.String'.
   at Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

5 的错误:

System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting from a character string to uniqueidentifier.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.HasMoreRows()
   at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

【问题讨论】:

  • 你得到什么错误?
  • GetGuid 应该可以工作。我会建议反对任何不必要地执行两个字符串转换的方法。请详细说明您拨打GetGuid时遇到的错误。
  • 任何使用Guid.Parse的东西。我希望你的最后一次尝试也可以。 任何时候当你在 Stack Overflow 问题中说“我得到错误”或“它无法编译”时,你应该指定这些错误是什么。事实上,看起来第一个和最后一个版本应该没问题。
  • @cja:你说它们是编译时错误。这些是例外,发生在执行时间。 请更加小心地提供准确的信息......你已经浪费了每个人的时间来追逐神话般的编译时失败。
  • 我现在很困惑 both 错误 2 和 3 是如何发生的。我的猜测是它们出现在不同的行上......我并不惊讶投射到 string 失败,但鉴于投射失败说它是 GUID,目前还不清楚为什么投射到 @987654331 @ 会失败。

标签: c# sql-server sql-server-2008 data-migration


【解决方案1】:

你试过了吗:

Guid guid = new Guid((string)reader["integ_schemehistoryId"]);

【讨论】:

  • 是的,请参阅问题。 (也许你在我编辑问题之前发布了这个。)
  • 我认为你没有。 new Guid(... 使用构造函数,您的问题表明您已经尝试了静态方法Guid.Parse,SQLDataReader 方法.GetGuid 并直接从Reader 中的对象转换为(Guid),这3 种情况都没有使用new,即构造函数。
  • 对不起,你是对的。我得到:System.InvalidCastException:无法将“System.Guid”类型的对象转换为“System.String”类型。在 Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()
【解决方案2】:

尝试使用Guid.Parse method

Guid guid = return Guid.Parse((string)reader["integ_schemehistoryId"]);

【讨论】:

  • 查看我在问题中的第二次尝试。
  • @cja:你传入了错误的数据类型 - 如果调用正确,这可能会起作用,尽管这不是最好的方法。
  • @cja 将读取器值转换为字符串,因为 Parse 方法期望字符串作为参数
  • 当答案只是“尝试使用 Guid.Parse 方法”时,我投了反对票
  • @cja 我还提供了一个如何正确使用 Guid.Parse 方法的链接
【解决方案3】:

正如其他答案所暗示的,您应该尝试:

Guid guid = Guid.Parse(reader["integ_schemehistoryId"].ToString())

您可能还想检查您的存储过程和表,那里可能有问题。

【讨论】:

    【解决方案4】:

    该错误是由 SQL 生成的。换句话说,您的 SQL 命令文本有问题。不是你的 C# 代码。

    【讨论】:

      【解决方案5】:

      您的数据或 SQL 有问题。第一种和第三种方法应该有效 - 我个人会使用第一种形式,因为它在我看来是最清晰的。

      但是看看堆栈跟踪:

      ... 在 System.Data.SqlClient.SqlDataReader.ReadInternal(布尔 setTimeout) 在 System.Data.SqlClient.SqlDataReader.Read() 在 Simego.DataSync.DynamicColumns.DataSourceRowOverride.get_EpochSchemeHistoryID()

      请注意,失败的是 Read() 调用,不是 GetGuid 或索引器。

      我的猜测是您的属性被多次获取,并且 有时 它有效 - 这就是为什么您在第二种方法中遇到强制转换异常 - 但对于 some 行,由于数据或 SQL 的某些问题而失败。由于我们不知道您的数据来自哪里,因此我们无法为您提供诊断以外的帮助,但这是您接下来应该关注的地方。

      【讨论】:

      • 左连接获取重复键?这样就可以了。
      【解决方案6】:
          object val = reader[0];
          Guid g;
          if ( Guid.TryParse(val, out g) )
          {
              return g;
          } 
          else 
          {
              Trace.WriteLine("Error: " + g == null ? string.Empty : g.ToString());   
          }
      

      【讨论】:

        【解决方案7】:

        在 Oracle 数据库中:

        "ID" RAW(16) DEFAULT SYS_GUID() NOT NULL ENABLE, 
        

        这段代码对我有用:

        using (IDataReader dr = ... )
            {
                while (dr.Read())
                {
                    var Id = new Guid();
                    if (!(dr["ID"] is DBNull)){
                        Id = new Guid((byte[])dr.GetValue(dr.GetOrdinal("ID")));
                    }                   
                }
                dr.Close();
            } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-08
          • 2018-12-24
          • 2017-08-28
          • 1970-01-01
          • 2011-03-07
          • 2012-12-06
          • 2010-10-12
          • 1970-01-01
          相关资源
          最近更新 更多