假设我有一个包含2个表的数据库,其中包含以下名称(tbl1
和tbl2
)。
上表中的每一个都有不同的列数,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...
答案 0 :(得分:4)
使用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;
}
注意:我使用这样的代码不是为了创建DataTable,而是将读取的行转换为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
答案 1 :(得分: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