简体   繁体   中英

How to iterate through IDataReader

I am using .Net 4.5, C#, Oracle 11g with EF 4.4.0.0

Existing Process

So, we have a DataModel which resembles the underlying Database structure and appropriate Entity Objects created as classes in our application. We are not always using EF to load the data as sometimes we use stored procedures to load data to the client and then map the data record by record the Entity classes in our application.

The existing code

var dataTable = new DataTable();
var accounts = new Dictionary<Decimal, ApplicationDomain.MainView.EMPLOYEE_MASTER>();

using (var cmd = new OracleCommand("PKG_TEST.GetAllEmployees", (OracleConnection)Db.Connection))
{
    cmd.Parameters.Add(new OracleParameter("DEPT_ID", userBankId));
    cmd.Parameters.Add(new OracleParameter("EMPLOYEE_P", OracleDbType.RefCursor, 0, ParameterDirection.Output, true, 0, 0, string.Empty, DataRowVersion.Default, Convert.DBNull));
    cmd.CommandType = CommandType.StoredProcedure;

    Db.Open();
    using (IDataReader dataReader = cmd.ExecuteReader())
    {
        try
        {
            dataTable.Load(dataReader );

            foreach (BusinessObjectBuilder<ApplicationDomain.MainView.EMPLOYEE_MASTER> employeeBuilder in
                dataTable.Rows.Cast<DataRow>().Select(row => new BusinessObjectBuilder<ApplicationDomain.MainView.EMPLOYEE_MASTER>(row)).Where(
                        accountBuilder => ((IBusinessObjectBuilder<ApplicationDomain.MainView.EMPLOYEE_MASTER>)employeeBuilder).Value != null))
            {
                var employee = ((IBusinessObjectBuilder<ApplicationDomain.MainView.EMPLOYEE_MASTER>)employeeBuilder).Value;
                try
                {
                    if (!employees.ContainsValue(employee))
                    {
                        employees.Add(employee.EMPLOYEE_ID, employee);
                    }
                    else
                    {
                        _log.InfoFormat("Employee ID already exists for this Department : Employee Id{0}", employee.EMPLOYEE_ID);
                    }
                }
                catch { }
            }
        }
        finally
        {
            if (dataReader != null && !dataReader.IsClosed)
            {
                dataReader.Close();
            }
        }
    }
}

The BusinessObjectBuilder class takes each row of EMPLOYEE and maps it with the Entity properties as we have defined in the application. Currently this is being done for every row of the data-table, after its been loaded with the data from the IDataReader.

What I am looking for

We are looking to get rid of the part where the DataTable is being loaded with data from the reader. I want to directly use the BusinessObjectBuilder with rows/records from dataReader object and map it to corresponding Entity properties.

As you can see above, the process loops through every single row inside the datatable, successfully maps each record into an Entity object and send it back, which will be added to a Dictionary , with the EMPLOYEE_ID as the key.

Problem

I cannot find a way to iterate through the dataReader object, get individual record and then do the process being done through BusinessObjectBuilder , add it to the Dictionary , with the EMPLOYEE_ID as the key.

Is there any way we can iterate through an IDataReader instance, the same way or some other way like we do with a DataTable?

Use the Read method to read the next record, and GetValue to get the value from a column:

while(dataReader.Read()) 
{
  var value1 = reader.GetValue(0); // first column
  var value2 = reader.GetValue(1); // second column
}

I would add overloads to BusinessObjectBuilder to read from an IDataReader instead of replacing the DataTable methods (in case you need them in the future).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM