4

为了将 ExpandoObjects 塞入类似以下两个网格的网格中,我们进行了两次尝试。

这不起作用:

var data = _d.Query<dynamic>(_script);         // returns IEnumerable<ExpandoObject>

IDictionary<string, object> c = (IDictionary<string, object>)data.FirstOrDefault();
DataTable dt = new DataTable();

dt.BeginLoadData();
dt.Columns.AddRange(c.Keys.Select(k => new DataColumn(k)).ToArray());
data.Select(r => dt.Rows.Add((r as IDictionary<string, object>).Values.ToArray()));
dt.EndLoadData();

但这确实:

dt.Columns.AddRange(c.Keys.Select(k => new DataColumn(k)).ToArray());
foreach (IDictionary<string, object> r in data)
  dt.Rows.Add(r.Values.ToArray());

为什么?

4

3 回答 3

1

选择方法

在通过直接调用其 GetEnumerator 方法或使用 Visual C# 中的 foreach 或 Visual Basic 中的 For Each 枚举对象之前,不会执行此方法表示的查询。

所以这个选择永远不会执行:

data.Select(r => dt.Rows.Add((r as IDictionary<string, object>).Values.ToArray()));

参考http://msdn.microsoft.com/ru-ru/library/bb548891.aspx

于 2011-11-16T20:12:08.537 回答
0

我没有对此进行测试,但请尝试这样的事情:

data.Cast<Dictionary<string, object>>().ToList().ForEach(x => dt.Rows.Add(x.Values.ToArray()));
于 2011-11-16T16:49:14.713 回答
0

正如水手已经指出的那样,LINQ 是懒惰地评估的。将 a.LastOrDefault()放在查询的末尾会导致执行(因为通过尝试获取它将执行您的最后一个元素Select()),但是它会使您的代码看起来更糟!

根据定义,不应将 LINQ Select 用于副作用行为。我相信您应该能够看到,在您的问题中,选项 2 看起来比选项 1 干净得多。通过阅读选项 2,我可以很容易地理解,您正在将每个元素添加data到数据表中。通过阅读选项 1,我猜你正在对data变量做一些事情,这是错误的。

总之,只要坚持选项 2。当性能相同时(就是这种情况),尽量让你的代码“易于”阅读。一个随机的人应该能够在不通读整个内容的情况下获得大致的想法。

于 2011-11-16T22:18:20.337 回答