Put GetOrdinal Method to Good Use

How often do you see DataReader code that looks like this?

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    while (dr.Read())
    {
        int orderId = dr.GetInt32(0);
        string customerId = dr.GetString(1);
        int employeeId = dr.GetInt32(2);
        DateTime orderDate = dr.GetDateTime(3);
        double freight = dr.GetDouble(4);

        // do stuff
    }

    dr.Close();
}

If that looks like your code, you are not alone :-). Try searching codesearch.google.com for the following:

lang:c# (reader|dr)\.GetInt32\(

With the above code, anytime the order of columns in the SQL statement or stored procedure changes, the code is broken. And if you have lots of columns to read from, it’s a real nightmare to maintain the indexes.

The next time you write another DataReader loop, consider doing it this way instead:

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    int ORDER_ID = dr.GetOrdinal("OrderID");
    int CUSTOMER_ID = dr.GetOrdinal("CustomerID");
    int EMPLOYEE_ID = dr.GetOrdinal("EmployeeID");
    int ORDER_DATE = dr.GetOrdinal("OrderDate");
    int FREIGHT = dr.GetDecimal("Freight");

    while (dr.Read())
    {
        int orderId = dr.GetInt32(ORDER_ID);
        string customerId = dr.GetString(CUSTOMER_ID);
        int employeeId = dr.GetInt32(EMPLOYEE_ID);
        DateTime orderDate = dr.GetDateTime(ORDER_DATE);
        double freight = dr.GetDouble(FREIGHT);

        // do stuff
    }

    dr.Close();
}

Using GetOrdinal makes the code much more readable and maintainable. You are calling GetOrdinal just once for each column, any performance penalty is insignificant compared to the benefits. Be careful not to put the GetOrdinal code inside the while block as that will unnecessarily slow you down (about 3% according to this article).

Chinh Do

I occasionally blog about programming (.NET, Node.js, Java, PowerShell, React, Angular, JavaScript, etc), gadgets, etc. Follow me on Twitter for tips on those same topics. You can also find me on GitHub. See About for more info.

View Comments

Recent Posts

How to switch to a different Kubernetes context or namespace?

To list available contexts: kubectl config get-contexts To show the current context: kubectl config current-context…

2 years ago

How to ssh into Kubernetes pod

kubectl exec -it <podname> -- sh To get a list of running pods in the…

2 years ago

How to Create a Soft Symbolic Link (symlink) in Unix/Linux

# Create a soft symbolic link from /mnt/original (file or folder) to ~/link ln -s…

3 years ago

How to Configure Git Username and Email Address

git config --global user.name "<your name>" git config --global user.email "<youremail@somewhere.com>" Related Commands Show current…

3 years ago

Getting the Last Monday for Any Month with TypeScript/JavaScript

TypeScript/JavaScript function getLastMonday(d: Date) { let d1 = new Date(d.getFullYear(), d.getMonth() + 1, 0); let…

4 years ago

How to View Raw SMTP Email Headers in Outlook

I had to do some SMTP relay troubleshooting and it wasn't obvious how to view…

5 years ago