2011-09-16 7 views
2

データテーブルから対応するオブジェクトにデータを取得するには、どのような方法が良いですか?私は現在、それをやっているよりも効率的できれいな方法があると推測しています。データテーブルをオブジェクトに変換する方法

var username = dt_user.rows[0].columns[0]; 

ありがとう!

+2

参照フィールドは間違いなく効率的であるが、私が「きれいな」と呼ぶものではない。 'dt_user.rows [0] .columns [" USER_NAME "]'という名前で列を参照することはできますが、これはよりクリーンですが多少効率が悪いです(これはほとんど問題ではありません)。また、 'foreach'構文を使ってDataTableのすべての' DataRow'オブジェクトを反復することもできます。 – MusiGenesis

+1

詳細があまりにも多くないため、1つの値(スカラー)だけを読み込んでいる場合は、SqlCommand.ExecuteScalarを使用し、DataTableを埋め込まないでください。 –

答えて

2

System.Data.DataSetExtensionsの拡張機能を確認してください。これは、DataRowのさまざまなオーバーロードを持つ汎用拡張メソッドのフィールドを提供します。 NULL可能プリミティブ型をアクセスするとき

var username = dt_user.rows[0].columns[0]; 
//becomes 
var username = dt_user.rows[0].Field<String>(0); 

真の力が来る:

var integerValue = dataRow.Field<Int32?>("ColumnName"); 

詳しい情報はここで見つけることができます:序によって `DataRow`で http://msdn.microsoft.com/en-us/library/system.data.datarowextensions.aspx

2

あなたはこの記事ではヘルパークラスの恩恵を受けるかもしれません:あなたは、データは、あなたが期待するタイプを知っていればhttp://lozanotek.com/blog/archive/2007/05/09/Converting_Custom_Collections_To_and_From_DataTable.aspx

public class CollectionHelper 
{ 
    private CollectionHelper() 
    { 
    } 

    public static DataTable ConvertTo<T>(IList<T> list) 
    { 
     DataTable table = CreateTable<T>(); 
     Type entityType = typeof(T); 
     PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); 

     foreach (T item in list) 
     { 
      DataRow row = table.NewRow(); 

      foreach (PropertyDescriptor prop in properties) 
      { 
       row[prop.Name] = prop.GetValue(item); 
      } 

      table.Rows.Add(row); 
     } 

     return table; 
    } 

    public static IList<T> ConvertTo<T>(IList<DataRow> rows) 
    { 
     IList<T> list = null; 

     if (rows != null) 
     { 
      list = new List<T>(); 

      foreach (DataRow row in rows) 
      { 
       T item = CreateItem<T>(row); 
       list.Add(item); 
      } 
     } 

     return list; 
    } 

    public static IList<T> ConvertTo<T>(DataTable table) 
    { 
     if (table == null) 
     { 
      return null; 
     } 

     List<DataRow> rows = new List<DataRow>(); 

     foreach (DataRow row in table.Rows) 
     { 
      rows.Add(row); 
     } 

     return ConvertTo<T>(rows); 
    } 

    public static T CreateItem<T>(DataRow row) 
    { 
     T obj = default(T); 
     if (row != null) 
     { 
      obj = Activator.CreateInstance<T>(); 

      foreach (DataColumn column in row.Table.Columns) 
      { 
       PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName); 
       try 
       { 
        object value = row[column.ColumnName]; 
        prop.SetValue(obj, value, null); 
       } 
       catch 
       { 
        // You can log something here 
        throw; 
       } 
      } 
     } 

     return obj; 
    } 

    public static DataTable CreateTable<T>() 
    { 
     Type entityType = typeof(T); 
     DataTable table = new DataTable(entityType.Name); 
     PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); 

     foreach (PropertyDescriptor prop in properties) 
     { 
      table.Columns.Add(prop.Name, prop.PropertyType); 
     } 

     return table; 
    } 
} 
To see the full code in action, check this sample out: 

public class MyClass 
{ 
    public static void Main() 
    { 
     List<Customer> customers = new List<Customer>(); 

     for (int i = 0; i < 10; i++) 
     { 
      Customer c = new Customer(); 
      c.Id = i; 
      c.Name = "Customer " + i.ToString(); 

      customers.Add(c); 
     } 

     DataTable table = CollectionHelper.ConvertTo<Customer>(customers); 

     foreach (DataRow row in table.Rows) 
     { 
      Console.WriteLine("Customer"); 
      Console.WriteLine("---------------"); 

      foreach (DataColumn column in table.Columns) 
      { 
       object value = row[column.ColumnName]; 
       Console.WriteLine("{0}: {1}", column.ColumnName, value); 
      } 

      Console.WriteLine(); 
     } 

     RL(); 
    } 

    #region Helper methods 

    private static void WL(object text, params object[] args) 
    { 
     Console.WriteLine(text.ToString(), args); 
    } 

    private static void RL() 
    { 
     Console.ReadLine(); 
    } 

    private static void Break() 
    { 
     System.Diagnostics.Debugger.Break(); 
    } 

    #endregion 
} 
2

。あなたは完全に文字列のためにこれを行うことができます。

int型のため
string username = dt_user.rows[0][0].ToString(); 

と、この:

int userID = int.Parse(dt_user.rows[0][0].ToString()); 

それはまだ醜いですが。私はそうとカップルの拡張メソッドを記述します。

public static string ObjectToString(this object theObject) 
{ 
    if(!string.IsNullOrEmpty(theObject)) 
     return theObject.ToString(); 
    return string.Empty; 
} 

public static int ObjectToInt(this object theObject) 
{ 
    int result = 0; 
    if(!string.IsNullOrEmpty(theObject) && int.TryParse(theObject, out result)) 
    { 
     return result; 
    } 
    return -1; 
} 

そして私はこのようにそれを呼び出します。

string username = dt_user.rows[0][0].ObjectToString(); 
int userid = dt_user.rows[0][0].ObjectToInt(); 

つ以上の提案:あなたドン場合は、インデックスを使用して列名をアクセスしないでくださいやらなければならない。あなたは完全に言うことができますdt_user.rows[0]["username"].ToString();

そして、誰かがあなたの結果セットの特定の列の位置を変更する場合に予期せぬ結果/エラーからあなたを守ります。

関連する問題