DataReader kullanarak veri alma

DataReader kullanarak veri almak için Command nesnesinin bir örneğini oluşturun ve ardından bir veri kaynağından satır almak için Command.ExecuteReader'ı çağırarak bir DataReader oluşturun. DataReader, yordamsal mantığın bir veri kaynağından gelen sonuçları sırayla verimli bir şekilde işlemesine olanak tanıyan bir veri akışı sağlar. Veriler bellekte önbelleğe alınmadığı için büyük miktarda veri alırken DataReader iyi bir seçimdir.

Aşağıdaki örnekte, geçerli bir DataReader'ı temsil eden ve command geçerli bir Command nesnesini temsil eden DataReader kullanımı gösterilmektedir.reader

reader = command.ExecuteReader();  
reader = command.ExecuteReader()

Sorgu sonuçlarından bir satır almak için DataReader.Read yöntemini kullanın. Döndürülen satırın her sütununa, sütunun adını veya sıra numarasını DataReader'a geçirerek erişebilirsiniz. Ancak, en iyi performans için DataReader kendi yerel veri türlerindeki sütun değerlerine (GetDateTime, GetDouble, GetGuid, GetInt32 vb.) erişmenizi sağlayan bir dizi yöntem sağlar. Veri sağlayıcısına özgü DataReaders için türü belirtilmiş erişimci yöntemlerinin listesi için bkz OleDbDataReader . ve SqlDataReader. Temel alınan veri türünü bildiğinizde türü belirtilen erişimci yöntemlerinin kullanılması, sütun değeri alınırken gereken tür dönüştürme miktarını azaltır.

Aşağıdaki örnek bir DataReader nesnesi aracılığıyla yinelenir ve her satırdan iki sütun döndürür.

static void HasRows(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "SELECT CategoryID, CategoryName FROM Categories;",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();

        if (reader.HasRows)
        {
            while (reader.Read())
            {
                Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
                    reader.GetString(1));
            }
        }
        else
        {
            Console.WriteLine("No rows found.");
        }
        reader.Close();
    }
}
Private Sub HasRows(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;", _
          connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        If reader.HasRows Then
            Do While reader.Read()
                Console.WriteLine(reader.GetInt32(0) _
                  & vbTab & reader.GetString(1))
            Loop
        Else
            Console.WriteLine("No rows found.")
        End If

        reader.Close()
    End Using
End Sub

DataReader'i Kapatma

DataReader nesnesini kullanmayı bitirdiğinizde her zaman Close yöntemini çağırın.

Komutunuz çıkış parametreleri veya dönüş değerleri içeriyorsa, DataReader kapatılana kadar bu değerler kullanılamaz.

DataReader açıkken, Bağlan ion yalnızca bu DataReader tarafından kullanılır. Özgün DataReader kapatılana kadar başka bir DataReader oluşturma dahil olmak üzere Bağlan için komut yürütemezsiniz.

Not

Sınıfınızın Finalize yönteminde bir Bağlan ion, DataReader veya başka bir yönetilen nesne üzerinde Close veya Dispose çağırmayın. Sonlandırıcıda yalnızca sınıfınızın doğrudan sahip olduğu yönetilmeyen kaynakları serbest bırakın. Sınıfınız yönetilmeyen kaynaklara sahip değilse, sınıf tanımınıza Bir Finalize yöntemi eklemeyin. Daha fazla bilgi için bkz . Çöp Toplama.

NextResult kullanarak birden çok sonuç kümesi alma

DataReader birden çok sonuç kümesi döndürürse, sonuç kümelerini sırayla yinelemek için NextResult yöntemini çağırın. Aşağıdaki örnek, yöntemini kullanarak iki SELECT deyiminin sonuçlarının işlenmesini ExecuteReader gösterirSqlDataReader.

static void RetrieveMultipleResults(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "SELECT CategoryID, CategoryName FROM dbo.Categories;" +
          "SELECT EmployeeID, LastName FROM dbo.Employees",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();

        while (reader.HasRows)
        {
            Console.WriteLine("\t{0}\t{1}", reader.GetName(0),
                reader.GetName(1));

            while (reader.Read())
            {
                Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0),
                    reader.GetString(1));
            }
            reader.NextResult();
        }
    }
}
Private Sub RetrieveMultipleResults(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;" & _
          "SELECT EmployeeID, LastName FROM Employees", connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        Do While reader.HasRows
            Console.WriteLine(vbTab & reader.GetName(0) _
              & vbTab & reader.GetName(1))

            Do While reader.Read()
                Console.WriteLine(vbTab & reader.GetInt32(0) _
                  & vbTab & reader.GetString(1))
            Loop

            reader.NextResult()
        Loop
    End Using
End Sub

DataReader'dan şema bilgilerini alma

DataReader açıkken GetSchemaTable yöntemini kullanarak geçerli sonuç kümesi hakkındaki şema bilgilerini alabilirsiniz. GetSchemaTable , geçerli sonuç kümesinin şema bilgilerini içeren satır ve sütunlarla doldurulmuş bir DataTable nesne döndürür. DataTable, sonuç kümesinin her sütunu için bir satır içerir. Şema tablosunun her sütunu, sonuç kümesinin satırlarında döndürülen sütunların bir özelliğine eşler; burada ColumnName özelliğin adı ve sütunun değeri özelliğin değeridir. Aşağıdaki örnek DataReader için şema bilgilerini yazar.

static void GetSchemaInfo(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "SELECT CategoryID, CategoryName FROM Categories;",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();
        DataTable schemaTable = reader.GetSchemaTable();

        foreach (DataRow row in schemaTable.Rows)
        {
            foreach (DataColumn column in schemaTable.Columns)
            {
                Console.WriteLine(string.Format("{0} = {1}",
                   column.ColumnName, row[column]));
            }
        }
    }
}
Private Sub GetSchemaInfo(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;", _
          connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()
        Dim schemaTable As DataTable = reader.GetSchemaTable()

        Dim row As DataRow
        Dim column As DataColumn

        For Each row In schemaTable.Rows
            For Each column In schemaTable.Columns
                Console.WriteLine(String.Format("{0} = {1}", _
                  column.ColumnName, row(column)))
            Next
            Console.WriteLine()
        Next
        reader.Close()
    End Using
End Sub

OLE DB bölümleriyle çalışma

Hiyerarşik satır kümeleri veya bölümler (OLE DB türü DBTYPE_HCHAPTER, ADO türü adChapter), kullanılarak OleDbDataReaderalınabilir. Bölüm içeren bir sorgu DataReader olarak döndürülürse, bölüm bu DataReader'da bir sütun olarak döndürülür ve DataReader nesnesi olarak sunulur.

ADO.NET DataSet , tablolar arasındaki üst-alt ilişkileri kullanarak hiyerarşik satır kümelerini göstermek için de kullanılabilir. Daha fazla bilgi için bkz . DataSets, DataTables ve DataViews.

Aşağıdaki kod örneği, bir müşteri listesindeki her müşteri için siparişlerin bölüm sütununu oluşturmak için MSDataShape Sağlayıcısı'nı kullanır.

Using connection As OleDbConnection = New OleDbConnection(
    "Provider=MSDataShape;Data Provider=SQLOLEDB;" &
    "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")

    Using custCMD As OleDbCommand = New OleDbCommand(
        "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " &
        "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " &
        "RELATE CustomerID TO CustomerID)", connection)

        connection.Open()

        Using custReader As OleDbDataReader = custCMD.ExecuteReader()

            Do While custReader.Read()
                Console.WriteLine("Orders for " & custReader.GetString(1))
                ' custReader.GetString(1) = CompanyName  

                Using orderReader As OleDbDataReader = custReader.GetValue(2)
                    ' custReader.GetValue(2) = Orders chapter as DataReader  

                    Do While orderReader.Read()
                        Console.WriteLine(vbTab & orderReader.GetInt32(1))
                        ' orderReader.GetInt32(1) = OrderID  
                    Loop
                    orderReader.Close()
                End Using
            Loop
            ' Make sure to always close readers and connections.  
            custReader.Close()
        End Using
    End Using
End Using
using (OleDbConnection connection = new OleDbConnection(
    "Provider=MSDataShape;Data Provider=SQLOLEDB;" +
    "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"))
{
    using (OleDbCommand custCMD = new OleDbCommand(
        "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
        "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " +
        "RELATE CustomerID TO CustomerID)", connection))
    {
        connection.Open();

        using (OleDbDataReader custReader = custCMD.ExecuteReader())
        {

            while (custReader.Read())
            {
                Console.WriteLine("Orders for " + custReader.GetString(1));
                // custReader.GetString(1) = CompanyName  

                using (OleDbDataReader 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();
                }
            }
            // Make sure to always close readers and connections.  
            custReader.Close();
        }
    }
}

Oracle REF CURSOR'ları ile sonuç döndürme

Oracle için .NET Framework Veri Sağlayıcısı, sorgu sonucu döndürmek için Oracle REF CURSOR'larının kullanımını destekler. Oracle REF CURSOR işlevi olarak OracleDataReaderdöndürülür.

Yöntemini kullanarak ExecuteReader Oracle REF CURSOR'i temsil eden bir nesne alabilirsinizOracleDataReader. Ayrıca, bir OracleCommand veya daha fazla Oracle REF CURSOR'unu bir öğesini doldurmak için kullanılan için SelectCommand olarak döndüren bir DataSetOracleDataAdapter de belirtebilirsiniz.

Oracle veri kaynağından döndürülen bir BAŞV İMLECI'ne erişmek için sorgunuz için bir OracleCommand oluşturun ve REF İMLECI'ne Parameters başvuruda bulunan bir çıkış parametresini koleksiyonunuza OracleCommandekleyin. Parametrenin adı, sorgunuzdaki REF CURSOR parametresinin adıyla eşleşmelidir. parametresinin türünü olarak OracleType.Cursorayarlayın. OracleCommand.ExecuteReader() yöntemi, OracleCommand BAŞV İMLECI için bir OracleDataReader döndürür.

Birden OracleCommand çok BAŞV İMLECI döndürürse, birden çok çıkış parametresi ekleyin. yöntemini çağırarak farklı REF CURSOR'lara OracleCommand.ExecuteReader() erişebilirsiniz. çağrısı ExecuteReader() , ilk BAŞV İMLECI'ne başvuran bir OracleDataReader döndürür. Ardından sonraki REF CURSOR'larına erişmek için yöntemini çağırabilirsiniz OracleDataReader.NextResult() . Koleksiyonunuzdaki OracleCommand.Parameters parametreler REF CURSOR çıkış parametreleriyle ada göre eşleşse de, OracleDataReader bunlara koleksiyona Parameters eklendikleri sırayla erişir.

Örneğin, aşağıdaki Oracle paketini ve paket gövdesini göz önünde bulundurun.

CREATE OR REPLACE PACKAGE CURSPKG AS
  TYPE T_CURSOR IS REF CURSOR;
  PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,
    DEPTCURSOR OUT T_CURSOR);
END CURSPKG;  
  
CREATE OR REPLACE PACKAGE BODY CURSPKG AS
  PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,
    DEPTCURSOR OUT T_CURSOR)
  IS
  BEGIN
    OPEN EMPCURSOR FOR SELECT * FROM DEMO.EMPLOYEE;
    OPEN DEPTCURSOR FOR SELECT * FROM DEMO.DEPARTMENT;
  END OPEN_TWO_CURSORS;
END CURSPKG;

Aşağıdaki kod, koleksiyona türünde OracleType.CursorOracleCommand.Parameters iki parametre ekleyerek önceki Oracle paketinden REF CURSOR'larını döndüren bir OracleCommand oluşturur.

Dim cursCmd As OracleCommand = New OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn)  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
OracleCommand cursCmd = new OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn);  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  

Aşağıdaki kod, ve NextResult() yöntemlerini kullanarak Read() önceki komutun OracleDataReadersonuçlarını döndürür. REF CURSOR parametreleri sırayla döndürülür.

oraConn.Open()  
  
Dim cursCmd As OracleCommand = New OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn)  
cursCmd.CommandType = CommandType.StoredProcedure  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
  
Dim reader As OracleDataReader = cursCmd.ExecuteReader()  
  
Console.WriteLine(vbCrLf & "Emp ID" & vbTab & "Name")  
  
Do While reader.Read()  
  Console.WriteLine("{0}" & vbTab & "{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1), reader.GetString(2))  
Loop  
  
reader.NextResult()  
  
Console.WriteLine(vbCrLf & "Dept ID" & vbTab & "Name")  
  
Do While reader.Read()  
  Console.WriteLine("{0}" & vbTab & "{1}", reader.GetOracleNumber(0), reader.GetString(1))  
Loop  
' Make sure to always close readers and connections.  
reader.Close()  
oraConn.Close()  
oraConn.Open();  
  
OracleCommand cursCmd = new OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn);  
cursCmd.CommandType = CommandType.StoredProcedure;  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  
  
OracleDataReader reader = cursCmd.ExecuteReader();  
  
Console.WriteLine("\nEmp ID\tName");  
  
while (reader.Read())  
  Console.WriteLine("{0}\t{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1), reader.GetString(2));  
  
reader.NextResult();  
  
Console.WriteLine("\nDept ID\tName");  
  
while (reader.Read())  
  Console.WriteLine("{0}\t{1}", reader.GetOracleNumber(0), reader.GetString(1));  
// Make sure to always close readers and connections.  
reader.Close();  
oraConn.Close();  

Aşağıdaki örnek, oracle DataSet paketinin sonuçlarıyla doldurmak için önceki komutu kullanır.

Dim ds As DataSet = New DataSet()  
  
Dim adapter As OracleDataAdapter = New OracleDataAdapter(cursCmd)  
adapter.TableMappings.Add("Table", "Employees")  
adapter.TableMappings.Add("Table1", "Departments")  
  
adapter.Fill(ds)  
DataSet ds = new DataSet();  
  
OracleDataAdapter adapter = new OracleDataAdapter(cursCmd);  
adapter.TableMappings.Add("Table", "Employees");  
adapter.TableMappings.Add("Table1", "Departments");  
  
adapter.Fill(ds);  

Not

OverflowException'dan kaçınmak için, değeri DataRowiçinde depolamadan önce Oracle NUMBER türünden geçerli bir .NET Framework türüne dönüştürme işlemini de işlemenizi öneririz. OverflowException oluşup oluşmadığını belirlemek için olayını kullanabilirsinizFillError. Olay hakkında FillError daha fazla bilgi için bkz . DataAdapter Olaylarını İşleme.

Ayrıca bkz.