4

To shoehorn ExpandoObjects into something grids like the following two attempts were made.

This doesn't work:

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();

But this does:

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

Why?

Guy--L
  • 170
  • 2
  • 13

3 Answers3

1

Select Method

The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

So this select is never executed:

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

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

Andrii Startsev
  • 767
  • 5
  • 11
0

I haven't tested this, but try soemthing like this instead:

data.Cast<Dictionary<string, object>>().ToList().ForEach(x => dt.Rows.Add(x.Values.ToArray()));
James Johnson
  • 45,496
  • 8
  • 73
  • 110
0

As sailor already pointed out, LINQ is lazily evaluated. Placing a .LastOrDefault() on the end of your query will cause execution (because by trying to get the last element it will execute your Select()), however it will make your code look even worse!

By definition, LINQ Select should not be used for side-effecting behaviour. I believe you should be able to see that in your question option 2 looks much cleaner than option 1. By reading option 2, I can easily understand, that you are adding each element of data to the datatable. By reading option 1, I'd guess you're doing something to the data variable, which would be wrong.

In conclusion, just stick with option 2. When performance is the same (as this is the case), try to make your code as "easy" to read as possible. A random person should be able to get the general idea without reading through the whole thing.

Vladislav Zorov
  • 2,998
  • 19
  • 32