如何从DataTable提取指定列填充构造函数生成实体对象列表
VB.NET DataTable转ISAACService对象列表实现方案
现有代码核心问题
- 声明的
lst1、lst2未初始化,直接调用Add方法会触发空引用异常 - 列名常量
Summencode拼写与DataTable实际列名SummenCode(大写C)不匹配,会导致找不到列 - DataTable提供的列中不存在
Gesamtmenge字段,需要你确认字段映射逻辑,以下示例暂时用Anzahl列转换为Integer作为替代,你可以根据实际业务调整 - 未处理DBNull值,直接转换类型会抛出异常
- 空Catch块吞掉所有异常,无法排查错误
- 没有判断传入的List参数是否为空,稳定性不足
修正后完整代码
Imports System.IO Public Class MainForm ' 修正列名与DataTable实际值匹配 Private Const KostenArt As String = "KostenArt" Private Const UANR As String = "UANR" Private Const Ueberbegriff As String = "Ueberbegriff" Private Const Benennung As String = "Benennung" Private Const Anzahl As String = "Anzahl" Private Const Einheit As String = "Einheit" Private Const Einzelkosten As String = "Einzelkosten" Private Const SummenCode As String = "SummenCode" ' 修正大小写匹配DataTable列名 Public dt1, dt2 As DataTable Public lst1, lst2 As List(Of ISAACService) ' 窗体加载时初始化列表 Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load lst1 = New List(Of ISAACService)() lst2 = New List(Of ISAACService)() End Sub Private Sub btnDatei1_Click(sender As Object, e As EventArgs) Handles btnDatei1.Click If OpenFileDialog1.ShowDialog() = DialogResult.OK Then If File.Exists(OpenFileDialog1.FileName) Then dt1 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName) dgv1.DataSource = dt1 ' 转换前清空原有数据避免重复添加 lst1.Clear() lst1 = ConvertDataTableToListOfISAACService(dt1, lst1) End If End If End Sub Private Sub btnDatei2_Click(sender As Object, e As EventArgs) Handles btnDatei2.Click If OpenFileDialog1.ShowDialog() = DialogResult.OK Then dt2 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName) dgv2.DataSource = dt2 lst2.Clear() lst2 = ConvertDataTableToListOfISAACService(dt2, lst2) End If End Sub Private Sub btnVergleich_Click(sender As Object, e As EventArgs) Handles btnVergleich.Click ' 后续对比逻辑可以直接使用lst1和lst2 CompareDataTables(lst1, lst2) End Sub Private Sub CompareDataTables(ByVal lst1 As List(Of ISAACService), ByVal lst2 As List(Of ISAACService)) ' 你的对比逻辑实现 End Sub Private Function ConvertDataTableToListOfISAACService(dt As DataTable, lst As List(Of ISAACService)) As List(Of ISAACService) ' 自动初始化传入的空列表 If lst Is Nothing Then lst = New List(Of ISAACService)() If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return lst Try For Each row As DataRow In dt.Rows ' 处理DBNull值,设置默认值 Dim kostenArtVal As String = If(row.IsNull(KostenArt), String.Empty, row(KostenArt).ToString()) Dim uanrVal As String = If(row.IsNull(UANR), String.Empty, row(UANR).ToString()) Dim ueberbegriffVal As String = If(row.IsNull(Ueberbegriff), String.Empty, row(Ueberbegriff).ToString()) Dim benennungVal As String = If(row.IsNull(Benennung), String.Empty, row(Benennung).ToString()) Dim anzahlVal As Double = If(row.IsNull(Anzahl), 0.0, CDbl(row(Anzahl))) Dim einheitVal As String = If(row.IsNull(Einheit), String.Empty, row(Einheit).ToString()) Dim einzelkostenVal As Double = If(row.IsNull(Einzelkosten), 0.0, CDbl(row(Einzelkosten))) ' 注意:DataTable无Gesamtmenge列,此处暂时用Anzahl转Integer替代,你可根据实际业务修改映射逻辑 Dim gesamtmengeVal As Integer = If(row.IsNull(Anzahl), 0, CInt(row(Anzahl))) Dim summenCodeVal As String = If(row.IsNull(SummenCode), String.Empty, row(SummenCode).ToString()) Dim isaac As New ISAACService(kostenArtVal, uanrVal, ueberbegriffVal, benennungVal, anzahlVal, einheitVal, einzelkostenVal, gesamtmengeVal, summenCodeVal) lst.Add(isaac) Next Catch ex As Exception ' 输出错误提示方便排查 MessageBox.Show($"转换数据出错:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try Return lst End Function End Class
注意事项
如果Gesamtmenge字段有其他映射逻辑,你只需要修改gesamtmengeVal的赋值代码即可,比如如果对应DataTable的Summenkosten列就把字段名换成"Summenkosten"。
内容的提问来源于stack exchange,提问作者idontgetit
相关产品推荐
相关产品推荐

