1

假设我有一个数据库,其中包含 2 个具有以下名称 (tbl1tbl2) 的表。上面的每个表都有不同的列数,tbl1有 3列,tbl2有 4 列。

我需要将上述每个表格复制到DataTable.

当然,我可以像下面的代码一样手动完成:

    class 
    {  
      public Main()  
      {
        // for tbl1 with 3 columns.
        string sql = "select * from tbl1"
        MySqlCommand com = new MySqlCommand(sql, con);
        MySqlDataReader dr = com.ExecuteDataReader();
        DataTable dt = GetDataTable(3);

        while (dr.Read())
        {
          if (dr.HasRows)
          {
            dt.Rows.Add(dr[0], dr[1], dr[2]);  <---- Point of interest
          }
        }

        // for tbl2 with 4 columns.
        string sql = "select * from tbl2";
        MySqlCommand com = new MySqlCommand(sql, con);
        MySqlDataReader dr = com.ExecuteDataReader();
        DataTable dt = GetDataTable(4);

        while (dr.Read())
        {
          if (dr.HasRows)
            {
              dt.Rows.Add(dr[0], dr[1], dr[2], dr[3]);  <---- Point of interest
            }
        }
    }

      public DataTable GetDataTable(int columnCount)
      {
        DataTable dt = new DataTable();

        if (columnCount > 0)
        {
          for (int i = 0; i < length; i++)
          {
            dt.Columns.Add(i.ToString(), typeof(object));
          }
        }
        return dt;
      }
    }  

但我想做的是以自动化的方式进行上述过程,特别是在我指示箭头的部分。

有没有一种方法可以像在列上那样动态添加行?

我在想我可以通过使用生成将行添加为字符串的过程并将该字符串作为命令调用的函数来动态添加行,但我真的很迷茫,不知道该怎么做......请看下面的代码.

EX:    
String generated from a function base on number of columns:
    "dt.Rows.Add(dr[0], dr[1], dr[2], dr[3])"
Then, use the string as a command to add rows...
4

2 回答 2

4

使用数据读取器的 GetSchemaTable 方法找出您有多少列。

像这样的东西(例如未经测试的代码):

public DataTable ReadTable(string sql, params object[] parameters) {


    using (var cmd = CreateCommand(sql, parameters))
        {
            var reader = cmd.ExecuteReader();
            if (reader == null)
            {
                return null;
            }

            var schemaTable = reader.GetSchemaTable();
                            DataTable dt = GetTable(schemaTable);

            while (reader.Read())
            {
                var values = new object[reader.FieldCount];
                reader.GetValues(values);
                                    dt.Rows.Add(values);

            }
        }
}

private DataTable GetTable(DataTable schemaTable) {
        if (schemaTable == null || schemaTable.Rows.Count == 0)
        {
            return null;
        }

        var dt = new DataTable();
        foreach (DataRow schemaRow in schemaTable.Rows)
        {
            var col = new DataColumn
            {
                ColumnName = schemaRow["ColumnName"].ToString(),
                                    DataType = schemaRow["DataType"]
                                  // use the debugger to find out the name of the type column in the schematable, 
                                  // and any other properties you need
            };
                            dt.Columns.Add(col);
        }
        return dt;

}

注意:我使用这样的代码不是为了创建 DataTable,而是将读取的行转换为 IEnumerable 对象(我们正在使用一些 DB2 Entity Framework 库,它们不会使用 sql 语句自动执行此操作)。

正如许多人提到的,如果您只想读取 DataTable,请创建一个 DataAdapter 并使用 Fill() 方法。

// Assumes that connection is a valid SqlConnection object.
string queryString = 
 "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

http://msdn.microsoft.com/en-us/library/bh8kx08z(v=vs.80).aspx

于 2013-04-30T19:20:28.773 回答
1

这是填充数据集以获取结果的 VB 示例(从我的一个包装器修改)。

根本没有行数(由数据适配器为您完成)

Sub ExampleUsage()
    Dim ds as new dataset
    ExecuteDataSetFill(AnSqlConnection, "SELECT * FROM Something; SELECT * from SomethingElse", ds)
    Dim Tbl1 as datatable=ds.Tables(0)
    Dim Tbl2 as datatable=ds.Tables(1)
    ' both tables will ALREADY HAVE all the rows in them, there is no reader involved.
End Sub
    ''' <summary>
    ''' Performs a FILL operation on an adapter, populating the passed in dataset for the current "OpenConnection", returns the return value of the FILL command.
    ''' </summary>
    ''' <param name="sSQL">SQL to use for the command to issue</param>
    ''' <param name="dsToFill">a DataSet to FILL</param>
    ''' <returns>The Return Value of the FILL operation</returns>
    Public Overridable Function ExecuteDataSetFill(ByVal con As SqlClient.SqlConnection, ByVal sSQL As String, ByVal dsToFill As DataSet) As Integer
        Dim da As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter
        Dim com As SqlClient.SqlCommand = con.CreateCommand
        com.CommandText = sSQL
        da.SelectCommand = com
        Dim iOut As Integer
        dsToFill.EnforceConstraints = False
        Dim sw As Stopwatch = Stopwatch.StartNew
        Try
            iOut = da.Fill(dsToFill)
        Catch ex As Exception
            Throw New Exception("DataSet Error. " & vbCrLf & "SQL = " & sSQL & vbCrLf & "Error=" & ex.ToString, ex)
        End Try
        sw.Stop()
        Return iOut
    End Function
于 2013-04-30T23:45:09.213 回答