【问题标题】:Why does populating an ADO.NET DataTable from within a lambda expression result in an empty DataTable?为什么从 lambda 表达式中填充 ADO.NET DataTable 会导致空 DataTable?
【发布时间】:2015-05-31 15:03:15
【问题描述】:

我正在尝试从List<T> 填充.NET 4.5 DataTable,其中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);
    }
}

但是,如果我尝试在同一端使用 lambda 表达式:

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 循环工作正常时,为什么我在使用 lambda 表达式时看不到已添加的行?

奖励问题:有没有办法使用更简洁的 lambda 表达式语法而不是手动编写 foreach 循环来做我想做的事情?

【问题讨论】:

  • 第二个是返回一个数据表对象列表,但没有分配给任何东西。如果您要执行“var table = inputList.Select....”,那么对行计数会发生什么?
  • @StevenWood 我不确定这是否适用,因为 .Select() 表达式从每个项目映射到函数调用以将行添加到在 lambda 表达式之外定义的 dataTable .或者至少那是我认为它会做的,但代码显然没有完全符合我的意图。完整的 .Select() 语句在这里没有返回任何有意义的内容。

标签: c# lambda datatable ado.net


【解决方案1】:

我无法回答为什么,但我可以回答额外问题:为此,您应该使用List.ForEach 方法:

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

但请注意,它仅适用于 List 类型的值,而不适用于 IListIEnumerable,因此您可能必须调用 ToList()

【讨论】:

  • 这对 foreach(){} 没有优势(只有通过委托的可能性)+ 有解析 lambda 的开销 + 额外的调用 + 更差的可读性(长链等)。没有标准的主要原因可用于 IEnumerable 的 ForEach 扩展方法会混淆惰性和副作用。
【解决方案2】:
  1. Select 是一个迭代器。 Lambda 定义在枚举开始后如何填充 IEnumerable。但它是在您对 select 的结果使用 foreach 或使用 ToList() 或 ToArray() 或 GetEnumerator() 强制枚举后开始的。MoveNext()... 这是延迟执行。

  2. 不建议执行Add in Select等操作。由于在未来的 .NET 版本中默认可以并行执行,并且 Add 不能是线程安全的

在“oldschool” foreach 中没有什么不好的,当你有理由使用 lambdas 时:使用表达式树、捕获上下文、在强制传递委托/表达式的情况下快速创建匿名方法。

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2019-12-08
    • 2020-06-14
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2018-12-22
    • 2010-10-22
    相关资源
    最近更新 更多