 VB.NET -  
Preenchendo um DataTable com um 
DataReader
 
VB.NET -  
Preenchendo um DataTable com um 
DataReader
Para preencher um DataTable em um DataSet geralmente você usa um DataAdapter. certo ?
E se você precisar preencher um DataTable de um DataSet a partir de um DataReader ? Acha que é possível ?
Neste momento é que os conhecimentos básicos das propriedades e características OOP da linguagem VB.NET se fazem valer. Se você anda meio esquecido vou fazer uma reprise destes conceitos.
O ADO.NET é implementando em várias classes que podem ser divididas em dois grupos :
O xis da questão é que para preencher um DataTable usamos o método Fill do objeto DataAdapter e que o DataReader não possui o método Fill.
Mas se olharmos com mais atenção para a classe DbDataAdpater , classe a partir da qual todos os tipos xxxDataAdapter herdam, iremos perceber que ela expõe um método sobrecarregado e protegido para o método Fill. E , o melhor da estória, este método pode tomar um objeto IDataReader como argumento. Sua sintaxe é :
Overloads Protected Overridable Function Fill(DataSet, String, IDataReader, Integer, Integer) As Integer
Podemos então usar estes métodos . Certo ?
Sim , podemos usar estes métodos usando Reflection pois eles são protected.
Podemos então criar um método , função ou procedure para efetuar o preenchimento de um DataTable a partir de um DataReader. O código da rotina poderia ser o descrito abaixo:
| Sub PreencheDataSetDeDataReader(ByVal ds As DataSet, ByVal table As String, ByVal dr As IDataReader)         ' Cria um  xxxDataAdapter do mesmo tipo de um DataReader
        Dim tipoDataReader As Type = CObj(dr).GetType
        Dim nomeTipo As String = tipoDataReader.FullName.Replace("DataReader", "DataAdapter")
        Dim tipoDataAdapter As Type = tipoDataReader.Assembly.GetType(nomeTipo)
        Dim da As Object = Activator.CreateInstance(tipoDataAdapter)        ' invoca o método protegido Fill que toma um objeto IDataReader
        Dim args() As Object = {ds, table, dr, 0, 999999}        tipoDataAdapter.InvokeMember("Fill", BindingFlags.InvokeMethod Or BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, da, args)        ' fecha o DataReader
        dr.Close()End Sub | 
Vamos então , usando a rotina acima mostrar como podemos preencher um DataGrid com os dados de um DataTable preenchido a partir de um DataReader.
Inicie um novo projeto no VS.NET do tipo Windows Application usando a linguagem VB.NET e no formulário padrão insira um componente DataGrid , um componente Button e outro Label.
Declare os seguintes imports no projeto:
Imports
System.data.sqlclientAgora no evento Click do botão de comando insira o código que irá usar a rotina PreencheDataSetDeDataReader().:
| Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click         Dim cn As New SqlConnection("server=(local);trusted_connection=true;database=Northwind;Integrated Security=SSPI")
        cn.Open()        Dim cm As New SqlCommand("SELECT * FROM Employees", cn)
        Dim dr As SqlDataReader = cm.ExecuteReader
        Dim ds As New DataSetPreencheDataSetDeDataReader(ds, "Empregados", dr)         DataGrid1.DataSource = ds.Tables("Empregados")End Sub | 
Estou efetuando uma conexão com o banco de dados Northwind do SQL Server e preenchendo o DataTable com os dados da tabela Employees.
Observe que estou passando o DataSet - ds , a tabela Empregados , e o DataReader - dr , que foi obtido anteriormente. Executando o projeto teremos o resultado abaixo:

Sem ter as noções de orientação a objeto jamais 
chegaríamos a esta solução.
Eu sei é apenas VB , mas eu gosto...
José Carlos Macoratti