.NET Standard 2.0中VB.NET Linq延迟绑定问题及优化方案问询
解决.NET Standard 2.0中VB.NET LINQ对DataRow的延迟绑定编译问题
首先得搞清楚为啥原来的代码在.NET Framework能跑,到了.NET Standard 2.0就报错——这是因为两个环境下VB编译器对LINQ查询里非泛型集合的延迟绑定支持逻辑不一样。在.NET Framework里,VB编译器允许直接在LINQ查询中对DataRowCollection(也就是_dtData.Rows)的元素用row("字段名")这种动态索引访问;但.NET Standard的编译器更严格,要求LINQ操作的是强类型集合,否则就会触发延迟绑定的编译错误。
你的循环方案确实能解决问题,但其实有更简洁且性能相当的优化方案,不用放弃LINQ的优雅写法:
优化方案:用AsEnumerable()转强类型集合+Field<T>方法
直接调用DataTable.AsEnumerable()把DataTable转为IEnumerable(Of DataRow)(强类型集合),再用DataRow.Field<T>()方法安全读取字段值,既能避开延迟绑定问题,又能保持LINQ的简洁性:
Dim resultados As List(Of ENTIDAD) = _dtData.AsEnumerable() _ .Skip(currentPage) _ .Take(If(pageSize = 0, totalrecords, pageSize)) _ .Select(Function(row) New ENTIDAD() With { ._IDENTIDAD = If(row.IsNull("IDENTIDAD"), Nothing, row.Field(Of Integer?)("IDENTIDAD")), ._CODENTIDAD = row.Field(Of String)("CODENTIDAD"), ._NOMBRE = row.Field(Of String)("NOMBRE") }) _ .ToList()
这个方案的优势
- 强类型更安全:
Field<T>方法会自动处理DBNull和可空类型,不用手动写TypeOf判断和类型转换,减少出错概率。比如row.Field(Of Integer?)("IDENTIDAD")会直接返回Integer?类型,字段为DBNull时自动返回Nothing,比你原来的If判断简洁得多。 - 性能和循环方案持平:LINQ的
Skip/Take/Select都是延迟执行的,实际遍历数据的次数和手动循环完全一致,内部实现也是优化过的,大数据量下性能差异可以忽略。 - 代码更简洁易维护:避免了重复的对象创建和列表添加代码,逻辑更清晰,后期修改字段时也更容易调整。
关于大数据量性能的担忧
你担心大数据量下的性能其实没必要——这个LINQ方案和你的循环方案底层执行逻辑几乎一致:都是先跳过指定行数,再取指定数量的行,逐行转换为ENTIDAD对象并收集到列表里。LINQ的额外开销极小,实际场景中根本感知不到。如果真要极致优化,直接按行索引遍历DataTable的收益微乎其微,反而会让代码变得复杂,得不偿失。
内容的提问来源于stack exchange,提问作者Nickholas
相关产品推荐
相关产品推荐

