Почему заполнение таблицы данных ADO.NET из лямбда-выражения приводит к созданию пустой таблицы данных?

1

Я пытаюсь заполнить DataTable.NET 4.5 из List<T>, где T - класс с свойством типа string.

У меня есть функция makeNewDataTable() которая создает экземпляр DataTable и добавляет к нему набор столбцов; эта часть работает нормально.

Когда я вручную перебираю список, в DataTable добавляется правильное количество строк (с правильными данными):

DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
    //inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
    foreach (var item in inputList)
    {
        dataTable.Rows.Add(item.Property, DBNull.Value);
    }
}

Однако, если я попытаюсь использовать выражение лямбда в том же конце:

DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
    inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
    //foreach (var item in inputList)
    //{
    //    dataTable.Rows.Add(item.Property, DBNull.Value);
    //}
}

то после, if Заключительное выражение } Я вижу, что dataTable.Rows.Count == 0.

Почему я не вижу, как строки добавляются, когда я использую выражение лямбда, когда закодированный вручную цикл foreach работает нормально?

Бонусный вопрос: есть ли способ сделать то, что я хочу, используя более сжатый синтаксис лямбда-выражений, а не вручную кодировать цикл foreach?

  • 0
    Второй возвращает список объектов таблицы данных, но никому не назначается. если вы должны были сделать "var table = inputList.Select ....", то рассчитывать на то, что происходит?
  • 0
    @StevenWood Я совсем не уверен, что это применимо, так как выражение .Select() сопоставляется из каждого элемента с вызовом функции, чтобы добавить строку в dataTable который определен вне лямбда-выражения. Или, по крайней мере, это было то, что я думал, что это будет делать, но код явно не делает то, что я хотел. Полный оператор .Select() здесь не возвращает ничего значимого.
Теги:
ado.net
lambda
datatable

2 ответа

0

Я не могу ответить на вопрос, почему, но я могу ответить на вопрос о бонусе: для этой цели вы должны использовать метод List.ForEach:

inputList.ForEach(item => dataTable.Rows.Add(item.Property, DBNull.Value));

Обратите внимание, что он доступен только для значения типа List, а не для IList или IEnumerable, поэтому вам может потребоваться вызвать ToList().

  • 0
    это не имеет преимуществ перед foreach () {} (только возможность передать делегат) + имеет дополнительные издержки для разбора лямбды + дополнительный вызов + худшая читаемость (длинные цепочки и т. д.). Основные причины, по которым нет стандартного метода расширения ForEach, доступного для IEnumerable <T > Смущает лень и побочные эффекты.
0
  1. Выбрать - итератор. Lambda определяет, как IEnumerable будет заполнен после начала перечисления. Но он начинается после использования foreach в результате выбора или принудительного перечисления с помощью ToList() или ToArray() или GetEnumerator(). MoveNext()... Это отложенное выполнение.

  2. Не рекомендуется выполнять такие операции, как "Добавить в выборе". Поскольку он может выполняться параллельно по умолчанию, в будущих версиях.NET и Add могут быть небезопасными потоки

В "oldschool" нет ничего плохого в foreach, вы должны использовать lambdas, когда у вас есть причины: работать с деревьями выражений, захватывать контексты, быстро создавать анонимные методы в сценариях, когда вы вынуждены передавать делегат/выражение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню