2014-12-05 66 views
0

我是新的ExpandoObject(的確,昨天我發現它)。我有下面的代碼,並想知道是否有某種方法將ExpandoObject轉換爲我不知道的DataTable?或者我必須使用反射來自己轉換它?ExpandoObject到DataTable

dynamic contacts = new List<dynamic>(); 

contacts.Add(new ExpandoObject()); 
contacts[0].Name = "Patrick Hines"; 
contacts[0].Phone = "206-555-0144"; 

contacts.Add(new ExpandoObject()); 
contacts[1].Name = "Ellen Adams"; 
contacts[1].Phone = "206-555-0155"; 
+0

'ExpandoObject'實現'IDictionary ',所以你可以使用任何代碼來將字典轉換爲'DataTable'。 – 2014-12-05 16:40:47

回答

2

這是我必須將其轉換。但如果有人有更好的方法,請讓我知道。

public DataTable ToDataTable(IEnumerable<dynamic> items) 
    { 
     var data = items.ToArray(); 
     if (data.Count() == 0) return null; 

     var dt = new DataTable(); 
     foreach (var key in ((IDictionary<string, object>)data[0]).Keys) 
     { 
      dt.Columns.Add(key); 
     } 
     foreach (var d in data) 
     { 
      dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray()); 
     } 
     return dt; 
    } 
+0

只要你的對象都具有相同的屬性(否則,佔據表結構有點困難),這是有效的。但是如果他們這樣做,爲什麼首先使用'ExpandoObject'?你可以聲明一個類來保存你的數據,這也對可維護性產生了積極的影響。 'class Contact {public string Name {get;組; } public string Phone {get;組; }}'沒有那麼多類型。 – 2014-12-05 16:53:42

+0

也許我可以從你那裏得到一些幫助,以更好地構建我的代碼。我正在處理列表中的一個複雜模型列表。我在模型中創建子列表的原因是因爲選擇是多選,它返回一個ID列表。我需要將它平鋪一個數據表,然後做一個批量複製到數據庫。因此,用一個新的屬性來創建這個模型的一個動態對象來保存一個串聯的ids。 ids的concat字符串最終存儲在db中的column/field中,爲1,2,3。我打開建議將嵌套列表平鋪到datable。 – NKD 2014-12-05 17:18:11

+0

這聽起來像一個非常具體的場景,需要比我們在評論中做的更多。嘗試[代碼評論](http://codereview.stackexchange.com/)。 – 2014-12-05 19:00:32

0

您可以使用此代碼。 Linq會幫助你:)

var contacts = new List<dynamic>(); 

contacts.Add(new ExpandoObject()); 
contacts[0].Name = "Patrick Hines"; 
contacts[0].Phone = "206-555-0144"; 

contacts.Add(new ExpandoObject()); 
contacts[1].Name = "Ellen Adams"; 
contacts[1].Phone = "206-555-0155"; 
// DataTable Instance... 
DataTable table = new DataTable(); 

//Get all properties of contract list items 
var properties = contacts.GetType().GetProperties(); 

// Remove contract list property 
properties = properties.ToList().GetRange(0, properties.Count() - 1).ToArray(); 

// Add column as named by property name 
properties.ToList().ForEach(p => table.Columns.Add(p.Name,typeof(string))); 

// Add rows from contracts list 
contacts.ForEach(x => table.Rows.Add(x.Name,x.Phone)); 
+0

與LINQ很好的工作。我選擇了另一種方法,因爲我想在將來重用該方法。你的方法工作得很好,但我不想重新輸入它,如果我需要轉換別的東西。 (即指定屬性名稱x.Name,x.Phone。)感謝您花時間研究此問題。 – NKD 2014-12-05 17:30:38