【问题标题】:Read data from SqlDataReader从 SqlDataReader 读取数据
【发布时间】:2021-09-20 18:19:39
【问题描述】:

我有一个 SQL Server 2008 数据库,我正在后端处理它。我正在研究 asp.net/C#

SqlDataReader rdr = cmd.ExecuteReader();  
while (rdr.Read())  
{              
   //how do I read strings here????  
}  

我知道读者有价值观。我的 SQL 命令是从表中仅选择 1 列。该列仅包含字符串。我想一一阅读阅读器中的字符串(行)。我该怎么做?

【问题讨论】:

    标签: c# asp.net sql-server-2008 sqldatareader


    【解决方案1】:
    string col1Value = rdr["ColumnOneName"].ToString();
    

    string col1Value = rdr[0].ToString();
    

    这些是objects,因此您需要转换它们或.ToString()

    【讨论】:

    • [] 运算符返回一个对象,您需要将其转换为字符串。
    • 如果您使用 reader.GetString(0) 之类的索引,它将使用您在查询中选择的第一列或表中的第一列。我有一个按顺序包含 3 列的表:ID、Dir、Email。我的命令选择目录和电子邮件。 reader.GetStrting(0) 会检索目录或 ID 吗?索引是基于 SQL Server 上的表本身还是基于您为从表中选择列而执行的查询?
    • @shenk 索引基于您选择参数的顺序。无论哪种方式,您最好使用列名或别名(即 rdr["ID"] 而不是 rdr[0])
    • @MarkAvenius 过去,通过数字序号进行索引比列名/别名获得了性能改进 - 不确定是否仍然如此
    • @BaltoStar 很有趣;我没有意识到这一点。但是,根据性能的差异(特别是与通过网络推送数据相比,基于您的应用程序),我通常会说查看列名的可读性和可维护性将胜过性能的任何边际改进。谢谢!
    【解决方案2】:

    把从"ColumnName"所在的数据库返回的列的名称开始。如果是字符串,可以使用.ToString()。如果是其他类型,需要使用System.Convert进行转换。

    SqlDataReader rdr = cmd.ExecuteReader();
    while (rdr.Read())
    {
        string column = rdr["ColumnName"].ToString();
        int columnValue = Convert.ToInt32(rdr["ColumnName"]);
    }
    

    【讨论】:

      【解决方案3】:
      using(SqlDataReader rdr = cmd.ExecuteReader())
      {
          while (rdr.Read())
          {
              var myString = rdr.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
              // Do somthing with this rows string, for example to put them in to a list
              listDeclaredElsewhere.Add(myString);
          }
      }
      

      【讨论】:

        【解决方案4】:

        简单来说,如果您的查询返回 column_name 并且它包含一个字符串:

        while (rdr.Read())
        {
            string yourString = rdr.getString("column_name")
        }
        

        【讨论】:

        • 目前阅读器上的.getXXX方法只接受整数序数。
        【解决方案5】:

        其实我自己也觉得可以这样:

        while (rdr.read())
        {  
          string str = rdr.GetValue().ToString().Trim();  
        }
        

        【讨论】:

        • 我看不出这种方法比其他方法更复杂。 Trim() 没有在问题中提到,所以在这里,但在其他答案中没有。
        【解决方案6】:
        while(rdr.Read())
        {
           string col=rdr["colName"].ToString();
        }
        

        会有用的

        【讨论】:

        • toString() is not valid 应该是 .ToString() 仅供参考
        • @MethodMan 感谢您的信息。我根据您的建议编辑了我的答案。
        • 嗨,我如何将行作为对象而不是按列?例如 {id:1,name:'John'}
        • 如果我想要下面的东西怎么办。 if(rdr[0]){ //在这里做点什么 }else if(rdr[1]){ //在这里做点什么
        【解决方案7】:

        我有一个辅助函数,例如:

          public static string GetString(object o)
            {
                if (o == DBNull.Value)
                    return "";
        
                return o.ToString();
            }
        

        然后我用它来提取字符串:

         tbUserName.Text = GetString(reader["UserName"]);
        

        【讨论】:

        • Standard Convert.ToString(o) 也一样,因为 DBNull 是 IConvertible,而 DBNull.ToString() 返回 string.Empty。
        • 你是对的,但我不确定我发布此内容时是否这样做。
        【解决方案8】:

        对于单个结果:

        if (reader.Read())
        {
            Response.Write(reader[0].ToString());
            Response.Write(reader[1].ToString());
        }
        

        对于多个结果:

        while (reader.Read())
        {
            Response.Write(reader[0].ToString());
            Response.Write(reader[1].ToString());
        }
        

        【讨论】:

          【解决方案9】:

          想把我的辅助方法分享给能用的人:

          public static class Sql
          {
              public static T Read<T>(DbDataReader DataReader, string FieldName)
              {
                  int FieldIndex;
                  try { FieldIndex = DataReader.GetOrdinal(FieldName); }
                  catch { return default(T); }
          
                  if (DataReader.IsDBNull(FieldIndex))
                  {
                      return default(T);
                  }
                  else
                  {
                      object readData = DataReader.GetValue(FieldIndex);
                      if (readData is T)
                      {
                          return (T)readData;
                      }
                      else
                      {
                          try
                          {
                              return (T)Convert.ChangeType(readData, typeof(T));
                          }
                          catch (InvalidCastException)
                          {
                              return default(T);
                          }
                      }
                  }
              }
          }
          

          用法:

          cmd.CommandText = @"SELECT DISTINCT [SoftwareCode00], [MachineID] 
                              FROM [CM_S01].[dbo].[INSTALLED_SOFTWARE_DATA]";
          using (SqlDataReader data = cmd.ExecuteReader())
          {
              while (data.Read())
              {
                  usedBy.Add(
                      Sql.Read<String>(data, "SoftwareCode00"), 
                      Sql.Read<Int32>(data, "MachineID"));
              }
          }
          

          helper方法可以转换成你喜欢的任何值,如果不能转换或者数据库值为NULL,结果将为null。

          【讨论】:

          • 一段不错的代码,我将其修改为扩展方法,效果很好reader.GetColumn&lt;int&gt;("M_ID");
          【解决方案10】:

          我知道这有点老了,但是如果您正在将 SqlDataReader 的内容读入一个类,那么这将非常方便。 reader 和 class 的列名应该相同

          public static List<T> Fill<T>(this SqlDataReader reader) where T : new()
                  {
                      List<T> res = new List<T>();
                      while (reader.Read())
                      {
                          T t = new T();
                          for (int inc = 0; inc < reader.FieldCount; inc++)
                          {
                              Type type = t.GetType();
                              string name = reader.GetName(inc);
                              PropertyInfo prop = type.GetProperty(name);
                              if (prop != null)
                              {
                                  if (name == prop.Name)
                                  {
                                      var value = reader.GetValue(inc);
                                      if (value != DBNull.Value)
                                      { 
                                          prop.SetValue(t, Convert.ChangeType(value, prop.PropertyType), null);
                                      }
                                      //prop.SetValue(t, value, null);
          
                                  }
                              }
                          }
                          res.Add(t);
                      }
                      reader.Close();
          
                      return res;
                  }
          

          【讨论】:

          • 这应该是推荐的答案。返回类型列表的非常通用的方法。
          【解决方案11】:

          我会反对在这里使用SqlDataReader; ADO.NET 有很多 边缘情况和复杂情况,根据我的经验,大多数手动编写的 ADO.NET 代码在至少一种方式(通常是微妙的和上下文相关的)中被破坏。

          存在避免这种情况的工具。例如,在这种情况下,您想读取一列字符串。 Dapper 让这一切变得无痛:

          var region = ... // some filter
          var vals = connection.Query<string>(
              "select Name from Table where Region=@region", // query
              new { region } // parameters
          ).AsList();
          

          Dapper 在这里处理所有参数化、执行和行处理 - 以及 ADO.NET 的许多其他蹩脚细节。 &lt;string&gt; 可以替换为 &lt;SomeType&gt; 以将整行具体化为对象。

          【讨论】:

            【解决方案12】:

            我通常以这种方式通过数据阅读器读取数据。只是添加了一个小例子。

            string connectionString = "Data Source=DESKTOP-2EV7CF4;Initial Catalog=TestDB;User ID=sa;Password=tintin11#";
            string queryString = "Select * from EMP";
            
            using (SqlConnection connection = new SqlConnection(connectionString))
            using (SqlCommand command = new SqlCommand(queryString, connection))
                        {
                            connection.Open();
            
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                if (reader.HasRows)
                                {
                                    while (reader.Read())
                                    {
                                        Console.WriteLine(String.Format("{0}, {1}", reader[0], reader[1]));
                                    }
                                }
                                reader.Close();
                            }
                        }
            

            【讨论】:

              【解决方案13】:

              你必须readdatabase column这里。你可以看看下面的代码 sn-p

                              string connectionString = ConfigurationManager.ConnectionStrings["NameOfYourSqlConnectionString"].ConnectionString;
                              using (var _connection = new SqlConnection(connectionString))
                              {
                                  _connection.Open();
              
                                  using (SqlCommand command = new SqlCommand("SELECT SomeColumnName FROM TableName", _connection))
                                  {
              
                                      SqlDataReader sqlDataReader = command.ExecuteReader();
                                      if (sqlDataReader.HasRows)
                                      {
                                          while (sqlDataReader.Read())
                                          {
                                              string YourFirstDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString(); // Remember Type Casting is required here it has to be according to database column data type
                                              string YourSecondDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString();
                                              string YourThridDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString();
              
                                          }
                                      }
                                      sqlDataReader.Close();
                                  }
                                  _connection.Close();
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-02-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多