title: Convert DataRow value to strongly typed value
body: <p>I want to convert a value from a DataRow to a strongly typed variable. I thought about something like:</p>
  
  <pre><code>int id = row.Field&lt;int&gt;("ID");
  </code></pre>
  
  <p>But the problem is, that our standard Db-Select returns a DataTable <strong>where every value is type of string</strong>. Means every value is object there and columns doesn't have specific type. By this <code>Field&lt;T&gt;</code> throws InvalidCastException because i try to cast object to int.</p>
  
  <p>So i did something by my own:</p>
  
  <pre><code>    public static T ConvertTo&lt;T&gt;(this DataRow row, string columnName)
      {
          T returnValue = default(T);
  
          Type typ = Nullable.GetUnderlyingType(typeof(T));
  
          if ((row != null) &amp;&amp;
              (row[columnName] != null) &amp;&amp;
              (!Convert.IsDBNull(row[columnName])))
          {
              if (typ == null)
              {
                  returnValue = (T)Convert.ChangeType(row[columnName], typeof(T));
              }
              else
              {
                  returnValue = (T)Convert.ChangeType(row[columnName], typ);
              }
          }
  
          return returnValue;
      }
  </code></pre>
  
  <p>This method works as expected. I can convert nullable values, strings and value types. Ok i need to catch exception if someone input bullshit like own types. But else it's fine.</p>
  
  <p>But if i load a DataTable with 30000 rows and 20 Columns and want to use this method to convert each value for object creation i got huge performance lack. If iam using <code>int id = Convert.ToInt32(row["ID"]);</code> and so on for each value it is 5-6 times faster then my general method. But i don't like to Convert them all manually especially if there are much <code>DBNull.Value</code>. </p>
  
  <p>I think the problem is getting the underlying type by:</p>
  
  <pre><code>Type typ = Nullable.GetUnderlyingType(typeof(T));
  </code></pre>
  
  <p>This is reflaction call and slow down my method. Is this right? Is there someone who got the same problem and has a fast solution maybe?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Our Standard-Select works like this:</p>
  
  <pre><code>DbDataAdapter dataAdapter = new DbDataAdapter();
  dataAdapter.SelectCommand = cmd;
  
  dataSet = new DataSet();
  
  dataAdapter.Fill(dataSet);
  dtReturn = dataSet.Tables[0].Copy();
  </code></pre>
  
  <p>DbDataAdapter internaly uses an OracleDataAdapter.</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>For clarification iam doing the following (just small example):</p>
  
  <p>i have a class which represents a select query. For example:</p>
  
  <pre><code>public class Customer
  {
    public int Id{get;set}
    public string Name{get;set}
  }
  </code></pre>
  
  <p>In Database (Oracle) i have a Table "Customer" which got 2 Columns <code>Id number(5)</code> and <code>Name varchar2(100)</code>.</p>
  
  <p>Now i want to read all Customer and Convert them to Customer-Objects.
  So i read the Data via our standard Routine SqlSelect. This returns me a DataTable. The intern of this method is posted before under first UPDATE.</p>
  
  <p>Now i loop over every DataRow in this DataTable and Convert this Cell value for Object creation.</p>
  
  <pre><code>List&lt;Customer&gt; myList = new List&lt;Customer&gt;();
  foreach (DataRow row in SqlSelect())
  {
    Customer customer = new Customer();
    customer.Id = Convert.ToInt32(row["ID"]);
    customer.Name = Convert.ToString(row["NAME"]);
    myList.Add(customer);
  }
  </code></pre>
  
  <p>This would be fine in this way. But i want to convert like:</p>
  
  <pre><code>customer.Id = row.ConvertTo&lt;int&gt;("ID");
  </code></pre>
  
  <p>If my DataTable at row["ID"] would be int the Field Method can handle this well. Especialy if there are other columns which can be null etc. But in my case the row["ID"] (and all other values of every select) is string. So Field can't cast this. My ConvertTo does it but has huge performance lack on large tables.</p>