2013-04-30 119 views
1

说我有2代表具有下列名称(tbl1tbl2)的数据库。 上表中的每个表具有不同的列数,tbl1有3个,而tbl2有4列。如何动态生成DataTable以及动态生成Columns和Row?

我需要,在上述各表的复制在一个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... 
+0

你或许应该使用一个适配器和在数据表的'Fill'方法。 – LarsTech 2013-04-30 17:47:29

+0

或者你可以尝试DataTable.Load()方法 – Alexander 2013-04-30 17:48:37

+2

@Steve这是一个帮助网站,RTFM是不可接受的响应。要么帮助OP回答他的问题,要么不回应。另外,是的,我看到你有28484848的声望。我真的不在乎,这并不能令人满意。 – KyleM 2013-04-30 17:55:56

回答

3

使用DataReader的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; 

} 

注:我用这样的代码不创建一个数据表,但对读取行转换成一个IEnumerable对象(我们正在使用一些不使用sql语句自动执行此操作的DB2实体框架库)。

如前所述,如果你只是想读一个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

+0

非常感谢您的帮助gabnaim和@Darren,正是我所需要的将我推向正确的方向^ _^ – chad 2013-05-01 01:36:58

1

这是填充DataSet中,让您的结果的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 
+0

非常感谢您的帮助@ gabnaim和Darren,正是我需要将我推到右边方向^ _ ^ – chad 2013-05-01 01:37:59