2014年1月27日 星期一

如何使用C#將DataTable轉為自訂物件List<class>

前言

早期.Net開發者習慣使用ADO.NET來時做資料儲存,故像DataReader or DataTable來儲存資料其實還蠻常見的,但這種都屬於弱型別,個人覺得在維護上其實還蠻困難的,故Entity Freamwork出來後改變了很多開發模式,將資料物件化也變成一件很正常的事情,現在在維護舊的WebForm系統,即使使用ADO.NET Fill一個DataTable,我還是會將這些資料轉換成自定義的Class,也許多了一道工,但我覺得差這一點點時間,讓維護上更直覺是很重要的事,畢竟程式不是永遠都你一個人在維護而已阿 ! 故此篇文章將會將實務使用的function來做分享。

實作

自定義的class

image

而這是取得DataTable資料的function,為求Demo而塞一些假資料

image

而實際轉換的function如下,而通常我會新增一個class,讓其他程式能共用

public static class DataTableExtensions
{
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();

//取得DataTable所有的row data
foreach (var row in table.Rows)
{
var item = MappingItem<T>((DataRow)row, properties);
result.Add(item);
}

return result;
}

private static T MappingItem<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
if (row.Table.Columns.Contains(property.Name))
{
//針對欄位的型態去轉換
if (property.PropertyType == typeof(DateTime))
{
DateTime dt = new DateTime();
if (DateTime.TryParse(row[property.Name].ToString(), out dt))
{
property.SetValue(item, dt, null);
}
else
{
property.SetValue(item, null, null);
}
}
else if (property.PropertyType == typeof(decimal))
{
decimal val = new decimal();
decimal.TryParse(row[property.Name].ToString(), out val);
property.SetValue(item, val, null);
}
else if(property.PropertyType == typeof(double))
{
double val = new double();
double.TryParse(row[property.Name].ToString(), out val);
property.SetValue(item, val, null);
}
else if (property.PropertyType == typeof(int))
{
int val = new int();
int.TryParse(row[property.Name].ToString(), out val);
property.SetValue(item, val, null);
}
else
{
if (row[property.Name] != DBNull.Value)
{
property.SetValue(item, row[property.Name], null);
}
}
}
}
return item;
}
}


使用方式:

List<UserInfo> list = new List<UserInfo>(); 
DataTable dt = GetDataTable();
var result = DataTableExtensions.ToList<UserInfo>(dt).ToList();
list = result.OrderBy(c => c.UpdateDate).ToList();

此.cs檔可至此連結下載 (如有Bug請見諒,或自行擴充~)

沒有留言:

張貼留言