2014-12-05 99 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