我理解,我也用过类似的方法,要先将DataReader读音入DataTable中,再将表DataSet.Talbes.Add()到数据集中; 不过在类中返回数据读时,怎样关闭数据读和数据库连接呢?DataReader是连接状态使用的啊,下面是在类的方法中的代码(有省略): dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);是在关闭dr时才关闭连接,但怎样在类的实例中关闭dr呢?
/// <summary> /// Converts a SqlDataReader to a DataSet /// <param name='reader'> /// SqlDataReader to convert.</param> /// <returns> /// DataSet filled with the contents of the reader.</returns> /// </summary> public static DataSet convertDataReaderToDataSet(SqlDataReader reader) { DataSet dataSet = new DataSet(); do { // Create new data table DataTable schemaTable = reader.GetSchemaTable(); DataTable dataTable = new DataTable(); if ( schemaTable != null ) { // A query returning records was executed for ( int i = 0; i < schemaTable.Rows.Count; i++ ) { DataRow dataRow = schemaTable.Rows[ i ]; // Create a column name that is unique in the data table string columnName = ( string )dataRow[ "ColumnName" ]; //+ "<C" + i + "/>"; // Add the column definition to the data table DataColumn column = new DataColumn( columnName, ( Type )dataRow[ "DataType" ] ); dataTable.Columns.Add( column ); } dataSet.Tables.Add( dataTable ); // Fill the data table we just created while ( reader.Read() ) { DataRow dataRow = dataTable.NewRow(); for ( int i = 0; i < reader.FieldCount; i++ ) dataRow[ i ] = reader.GetValue( i ); dataTable.Rows.Add( dataRow ); } } else { // No records were returned DataColumn column = new DataColumn("RowsAffected"); dataTable.Columns.Add(column); dataSet.Tables.Add( dataTable ); DataRow dataRow = dataTable.NewRow(); dataRow[0] = reader.RecordsAffected; dataTable.Rows.Add( dataRow ); } } while ( reader.NextResult() ); return dataSet; }
让人费解
DataTable加入dataSet
dataset写数。这样确实不好。
建议听cqnimin() 的写sql来填充
while(datareader.read())
{
DataRow drow=dataset.某table.newrow();
drow[0]=datareader.get...(0);
...
drow[n]=datareader.get...(n);
dataset.某table.Rows.Add(drow);
}
不过在类中返回数据读时,怎样关闭数据读和数据库连接呢?DataReader是连接状态使用的啊,下面是在类的方法中的代码(有省略):
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);是在关闭dr时才关闭连接,但怎样在类的实例中关闭dr呢?
/// Converts a SqlDataReader to a DataSet
/// <param name='reader'>
/// SqlDataReader to convert.</param>
/// <returns>
/// DataSet filled with the contents of the reader.</returns>
/// </summary>
public static DataSet convertDataReaderToDataSet(SqlDataReader reader)
{
DataSet dataSet = new DataSet();
do
{
// Create new data table DataTable schemaTable = reader.GetSchemaTable();
DataTable dataTable = new DataTable(); if ( schemaTable != null )
{
// A query returning records was executed for ( int i = 0; i < schemaTable.Rows.Count; i++ )
{
DataRow dataRow = schemaTable.Rows[ i ];
// Create a column name that is unique in the data table
string columnName = ( string )dataRow[ "ColumnName" ]; //+ "<C" + i + "/>";
// Add the column definition to the data table
DataColumn column = new DataColumn( columnName, ( Type )dataRow[ "DataType" ] );
dataTable.Columns.Add( column );
} dataSet.Tables.Add( dataTable ); // Fill the data table we just created while ( reader.Read() )
{
DataRow dataRow = dataTable.NewRow(); for ( int i = 0; i < reader.FieldCount; i++ )
dataRow[ i ] = reader.GetValue( i ); dataTable.Rows.Add( dataRow );
}
}
else
{
// No records were returned DataColumn column = new DataColumn("RowsAffected");
dataTable.Columns.Add(column);
dataSet.Tables.Add( dataTable );
DataRow dataRow = dataTable.NewRow();
dataRow[0] = reader.RecordsAffected;
dataTable.Rows.Add( dataRow );
}
}
while ( reader.NextResult() );
return dataSet;
}
SqlDataReader myReader = myCommand.ExecuteReader();
使用 DataReader 对象的 Read 方法可从查询结果中获取行。通过向 DataReader 传递列的名称或序号引用,可以访问返回行的每一列。不过,为了实现最佳性能,DataReader 提供了一系列方法,它们将使您能够访问其本机数据类型(GetDateTime、GetDouble、GetGuid、GetInt32 等)形式的列值。有关类型化访问器方法的列表,请参阅 OleDbDataReader 类和 SqlDataReader 类。如果在基础数据类型未知时使用类型化访问器方法,将减少在检索列值时所需的类型转换量。以下代码示例循环访问一个 DataReader 对象,并从每个行中返回两个列。
while (myReader.Read())
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
myReader.Close();
DataReader 提供未缓冲的数据流,该数据流使过程逻辑可以有效地按顺序处理从数据源中返回的结果。由于数据不在内存中缓存,所以在检索大量数据时,DataReader 是一种适合的选择。关闭 DataReader
每次使用完 DataReader 对象后都应调用 Close 方法。如果 Command 包含输出参数或返回值,那么在 DataReader 关闭之前,将无法访问这些输出参数或返回值。请注意,当 DataReader 打开时,该 DataReader 将以独占方式使用 Connection。在初始 DataReader 关闭之前,将无法对 Connection 执行任何命令(包括创建另一个 DataReader)。多个结果集
如果返回的是多个结果集,DataReader 会提供 NextResult 方法来按顺序循环访问这些结果集,如以下代码示例所示。
SqlCommand myCMD = new SqlCommand("SELECT CategoryID, CategoryName FROM Categories;" +
"SELECT EmployeeID, LastName FROM Employees", nwindConn);
nwindConn.Open();SqlDataReader myReader = myCMD.ExecuteReader();do
{
Console.WriteLine("\t{0}\t{1}", myReader.GetName(0), myReader.GetName(1)); while (myReader.Read())
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));} while (myReader.NextResult());myReader.Close();
nwindConn.Close();
从 DataReader 中获取架构信息
当 DataReader 打开时,可以使用 GetSchemaTable 方法检索有关当前结果集的架构信息。GetSchemaTable 将返回一个填充了行和列的 DataTable 对象,这些行和列包含当前结果集的架构信息。对于结果集的每一列,DataTable 都将包含一行。架构表行的每一列都映射到在结果集中返回的列的属性,其中 ColumnName 是属性的名称,而列的值为属性的值。以下代码示例为 DataReader 写出架构信息。
DataTable schemaTable = myReader.GetSchemaTable();foreach (DataRow myRow in schemaTable.Rows)
{
foreach (DataColumn myCol in schemaTable.Columns)
Console.WriteLine(myCol.ColumnName + " = " + myRow[myCol]);
Console.WriteLine();
}
OLE DB 章节
分层行集或章节(OLE DB 类型 DBTYPE_HCHAPTER、ADO 类型 adChapter)可以使用 OleDbDataReader 来检索。当以 DataReader 的形式返回包含某章节的查询时,该章节将以此 DataReader 中列的形式返回,并公开为 DataReader 对象。ADO.NET DataSet 也可用于通过表间的父子关系来表示分层行集。有关的更多信息,请参阅创建和使用 DataSet。以下代码示例使用 MSDataShape 提供程序来为客户列表中的每个客户生成订单的章节列。
OleDbConnection nwindConn = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
"Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");OleDbCommand custCMD = new OleDbCommand("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
" APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " +
" RELATE CustomerID TO CustomerID)", nwindConn);
nwindConn.Open();OleDbDataReader custReader = custCMD.ExecuteReader();
OleDbDataReader orderReader;while (custReader.Read())
{
Console.WriteLine("Orders for " + custReader.GetString(1));
// custReader.GetString(1) = CompanyName orderReader = (OleDbDataReader)custReader.GetValue(2);
// custReader.GetValue(2) = Orders chapter as DataReader while (orderReader.Read())
Console.WriteLine("\t" + orderReader.GetInt32(1));
// orderReader.GetInt32(1) = OrderID
orderReader.Close();
}custReader.Close();
nwindConn.Close();
public class item
{
private string str1;
private string str2;
public item(string _str1, string _str2)
{
this.str1 = _str1;
this.str2 = _str2;
}
public string Str1
{
get
{
return str1;
}
set
{
this.str1=value;
}
}
public string Str2
{
get
{
return str2;
}
set
{
this.str2=value;
}
} }
然后用你返回的DataReader生成一个ArrayList,ArrayList的元素就是item
ArrayList items = new ArrayList();
items.Add(new item("asd","adf"));
items.Add(new item("value","dddd"));
this.dataGrid1.DataSource = items;