根据列值从数据集中提取第一个(最旧的)值

Extracting the First (Oldest) Value from Dataset Based on Column Value

我没有太多使用数据集的经验,也无法找到实现我想要实现的目标的最佳方法。

我基本上使用 SQL 查询创建数据集,然后我试图在 'Field' 列中找到一个特定值,然后如果 'Y' 在 'Flag'(与 'N')列在同一行然后我希望它将复选框的状态更改为已选中并更新标签文本。

我所拥有的似乎有效,但是如果没有返回数据,我会收到以下错误:

Object reference not set to an instance of an object

如果我将代码从 .FirstOrDefault() 稍微更改为 .First(),我会收到此错误:

Sequence contains no elements

下面列出了可能导致问题的代码部分。如果您需要了解其他任何内容,我会添加它。

    Dim sSQL As String
    sSQL =
        <SQL>
            SELECT MAX(UpdateTime) AS UpdateTime FROM AdminCS_Data_Current
            WHERE UpdateUser = |@@UpdateUser|
        </SQL>
    sSQL = Replace(sSQL, "@@UpdateUser", AdminCB.Text)
    Me.LastUserUpdate.Text = "Last Action: " & Format(ReturnDatabaseValue(sSQL, "UpdateTime", "Data"), "dd/MM/yyyy HH:mm:ss")

    Dim EmployeeDataset As New DataSet
    Try
        sSQL =
            <SQL>
                SELECT * FROM AdminCS_Data_Current
                WHERE UpdateUser = |@@UpdateUser| AND CONVERT(DATE, UpdateTime) = CAST(GETDATE() AS  DATE)
                ORDER BY UpdateTime ASC 
            </SQL>
        sSQL = Replace(sSQL, "@@UpdateUser", AdminCB.Text)
        EmployeeDataset = ReturnDataSet(sSQL, "Data")

        If EmployeeDataset IsNot Nothing Then
            Dim eData = EmployeeDataset.Tables(0)
            If (eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()("Flag")) IsNot Nothing Then
                If eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()("Flag").ToString.Trim = "Y" Then
                    TShtY.CheckState = CheckState.Checked
                    TShtTime.Text = Format(eData.Select("Field = 'Timesheets Checked'").First()("UpdateTime"), "HH:mm:ss")
                Else
                    TShtN.CheckState = CheckState.Checked
                End If
            End If
           ' The above two IF statements would be repeated several times on each change of "Field" 
        End If

看来这段代码不仅引入了效率低下,还引入了一个错误:

    If (eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()("Flag")) IsNot Nothing Then
        If eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()("Flag").ToString.Trim = "Y" Then
            TShtY.CheckState = CheckState.Checked
            TShtTime.Text = Format(eData.Select("Field = 'Timesheets Checked'").First()("UpdateTime"), "HH:mm:ss")
        Else
            TShtN.CheckState = CheckState.Checked
        End If
    End If

一开始应该是这样写的:

    Dim row = eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()

    If row IsNot Nothing Then
        If row("Flag").ToString.Trim = "Y" Then
            TShtY.CheckState = CheckState.Checked
            TShtTime.Text = Format(row("UpdateTime"), "HH:mm:ss")
        Else
            TShtN.CheckState = CheckState.Checked
        End If
    End If

更易于阅读、更高效并避免了该讨厌的错误。

此外,我更想看到这个:

    Dim row = eData.Select("Field = 'Timesheets Checked'").FirstOrDefault()

    If row IsNot Nothing Then
        If row("Flag").ToString.Trim = "Y" Then
            TShtY.Checked = True
            TShtTime.Text = CDate(row("UpdateTime").ToString("HH:mm:ss")
        Else
            TShtN.Checked = True
        End If
    End If

你不应该使用 CheckboxCheckState 除非它是三态的,也许你的是,但我怀疑它。至于 Format,我们不再使用 VB6 Toto。