來源 http://www.dotblogs.com.tw/rainmaker/archive/2013/11/05/126727.aspx
今天看同事分享時,看到他們將DataTable轉成物件時,使用for…each的方式。
雖然有很多的ORM框架可以幫我們做到同樣的效果,但如果手動要做的話,有那些方式呢?
4 |
public string CompId { get ; set ; } |
5 |
public string HandleUnit { get ; set ; } |
6 |
public string No { get ; set ; } |
方法1:使用for…each (for…next也可以)
02 |
DataTable dt = new DataTable(); |
03 |
dt.Columns.Add( "CompId" , typeof ( string )); |
04 |
dt.Columns.Add( "HandleUnit" , typeof ( string )); |
05 |
dt.Columns.Add( "No" , typeof ( string )); |
06 |
dt.Rows.Add( new object [] { "655" , "EBS" , "001" }); |
07 |
dt.Rows.Add( new object [] { "655" , "ODM" , "002" }); |
08 |
dt.Rows.Add( new object [] { "655" , "OCS" , "003" }); |
11 |
List<Document> Way1 = new List<Document>(); |
12 |
foreach (DataRow dr in dt.Rows) |
14 |
Document doc = new Document(); |
15 |
doc.CompId = dr.Field< string >( "CompId" ); |
16 |
doc.HandleUnit = dr.Field< string >( "HandleUnit" ); |
17 |
doc.No = dr.Field< string >( "No" ); |
01 |
public static class DataTableExtensions |
03 |
public static IList<T> ToList<T>( this DataTable table) where T : new () |
05 |
IList<PropertyInfo> properties = typeof (T).GetProperties().ToList(); |
06 |
IList<T> result = new List<T>(); |
08 |
foreach (var row in table.Rows) |
10 |
var item = CreateItemFromRow<T>((DataRow)row, properties); |
17 |
public static IList<T> ToList<T>( this DataTable table, Dictionary< string , string > mappings) where T : new () |
19 |
IList<PropertyInfo> properties = typeof (T).GetProperties().ToList(); |
20 |
IList<T> result = new List<T>(); |
22 |
foreach (var row in table.Rows) |
24 |
var item = CreateItemFromRow<T>((DataRow)row, properties, mappings); |
31 |
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new () |
34 |
foreach (var property in properties) |
36 |
property.SetValue(item, row[property.Name], null ); |
41 |
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties, Dictionary< string , string > mappings) where T : new () |
44 |
foreach (var property in properties) |
46 |
if (mappings.ContainsKey(property.Name)) |
47 |
property.SetValue(item, row[mappings[property.Name]], null ); |
方式2.1:如果欄位名稱跟物件屬性名稱相同,則直接對應。
1 |
DataTable dt2 = new DataTable(); |
2 |
dt2.Columns.Add( "CompId" , typeof ( string )); |
3 |
dt2.Columns.Add( "HandleUnit" , typeof ( string )); |
4 |
dt2.Columns.Add( "No" , typeof ( string )); |
5 |
dt2.Rows.Add( new object [] { "655" , "EBS" , "001" }); |
6 |
dt2.Rows.Add( new object [] { "655" , "ODM" , "002" }); |
7 |
dt2.Rows.Add( new object [] { "655" , "OCS" , "003" }); |
9 |
var Wary2 = dt2.ToList<Document>(); |
方式2.2:如果欄位名稱跟物件屬性名稱不同,則建立Dictionary型態的Mapping物件,如下,
01 |
DataTable dt3 = new DataTable(); |
02 |
dt3.Columns.Add( "CompId" , typeof ( string )); |
03 |
dt3.Columns.Add( "HandleUnit" , typeof ( string )); |
04 |
dt3.Columns.Add( "No" , typeof ( string )); |
05 |
dt3.Rows.Add( new object [] { "655" , "EBS" , "001" }); |
06 |
dt3.Rows.Add( new object [] { "655" , "ODM" , "002" }); |
07 |
dt3.Rows.Add( new object [] { "655" , "OCS" , "003" }); |
10 |
var mappings = new Dictionary< string , string >(); |
11 |
mappings.Add( "CompId" , "CompId" ); |
12 |
mappings.Add( "HandleUnit" , "HandleUnit" ); |
13 |
mappings.Add( "No" , "No" ); |
14 |
var Way3 = dt3.ToList<Document>(mappings); |
相信一定有一堆人會問說,為何要這樣做呢? 為何不使用ORM呢? 為什麼? 為什麼? …..等很多的疑問
同事回說,因為只是針對舊有的系統新增一個小的模組,而目前系統的Table有300多個,時間有限 … So…. 就先這樣搞…