Почему LINQ не работает для добавления DataRows в DataTable? - PullRequest
4 голосов
/ 16 ноября 2011

Чтобы развернуть 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());

Почему?

Ответы [ 3 ]

1 голос
/ 17 ноября 2011

Выбор метода

Запрос, представленный этим методом, не выполняется до тех пор, пока объект не будет перечислен ни путем непосредственного вызова его метода GetEnumerator, ни с помощью foreach в Visual C #, ни дляКаждый в Visual Basic.

Таким образом, этот выбор никогда не выполняется:

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

Ссылка http://msdn.microsoft.com/ru-ru/library/bb548891.aspx

0 голосов
/ 17 ноября 2011

Как уже отмечал моряк, LINQ лениво оценивают.Размещение .LastOrDefault() в конце вашего запроса приведет к выполнению (потому что, пытаясь получить последний элемент, он выполнит ваши Select()), однако сделает ваш код еще хуже!

По определению, LINQ Select не должен использоваться для побочного действия.Я полагаю, вы должны видеть, что в вашем вопросе вариант 2 выглядит намного чище, чем вариант 1. Прочитав вариант 2, я легко пойму, что вы добавляете каждый элемент data в таблицу данных.Читая вариант 1, я думаю, что вы что-то делаете с переменной data, что было бы неправильно.

В заключение, просто придерживайтесь варианта 2. Когда производительность такая же (как этослучай), постарайтесь сделать ваш код как можно более простым для чтения.Случайный человек должен быть в состоянии получить общее представление, не читая всего этого.

0 голосов
/ 16 ноября 2011

Я не проверял это, но попробуйте что-то вроде этого:

data.Cast<Dictionary<string, object>>().ToList().ForEach(x => dt.Rows.Add(x.Values.ToArray()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...