2016-10-19 6 views
0

Ich habe nicht viel Erfahrung mit der Arbeit mit DataSets und war nicht in der Lage, den besten Weg zu finden, um das zu erreichen, was ich erreichen möchte.Den ersten (ältesten) Wert aus dem Datensatz basierend auf dem Spaltenwert extrahieren

Ich erstellen im Grunde ein DataSet mit einer SQL-Abfrage und dann versuche ich, einen bestimmten Wert in der 'Feld' Spalte zu finden und dann, wenn ein 'Y' in der 'Flag' (wie ein 'N ') Spalte in derselben Zeile, dann möchte ich den Status eines Kontrollkästchens in "Geprüft" ändern sowie den Text einer Beschriftung aktualisieren.

Was ich habe, scheint aber zu funktionieren, wenn keine Daten zurückgegeben ich die unten Fehlermeldung erhalten:

Object reference not set to an instance of an object

Wenn ich den Code leicht von .FirstOrDefault() zu .First() Ich diesen Fehler zu ändern:

Sequence contains no elements

Der Teil des Codes, der das Problem verursacht, ist unten aufgeführt. Wenn Sie etwas anderes wissen, werde ich es in hinzufügen

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 
+0

Der Hauptpunkt der Verwendung von 'FirstOrDefault' ist, dass möglicherweise nichts in der Sequenz vorhanden ist, so dass Sie nicht einfach weitermachen und das Ergebnis verwenden können, als ob es existiert. Nachdem Sie 'FirstOrDefault' aufgerufen haben, müssen Sie das Ergebnis testen, um zu sehen, ob es' Nothing' zuerst heißt, und dann nur, wenn es nicht ist, also nur das Ergebnis verwenden, wenn es etwas ist. – jmcilhinney

+0

Wenn das nicht klar genug ist, denken Sie darüber nach. Angenommen, Sie betreten einen Raum, der null, eine oder mehrere Personen enthält, und ich sage Ihnen, dass Sie von der ersten Person, die Sie in diesem Raum treffen, $ 100 sammeln können. Wenn du reingehst und es keine Leute gibt, materialisieren sich $ 100 auf magische Weise in deiner Tasche? Natürlich können Sie das Geld nur dann abholen, wenn es eine Person gibt, von der es abgeholt werden kann. Ebenso können Sie das erste Element in einer Sequenz nur verwenden, wenn mindestens ein Element in dieser Sequenz vorhanden ist. 'First' benötigt mindestens einen Gegenstand, während' FirstOrDefault' 'Nothing' zurückgibt, wenn keine Gegenstände vorhanden sind. – jmcilhinney

+0

@jmcilhinney Ist das nicht das, was ich getan habe? Wenn es in der Sequenz nichts gibt, würde das IF (IsNot Nothing) nicht eingegeben werden und es würde direkt zum Ende IF gehen? –

Antwort

2

Es scheint, dass dieser Code nicht nur iunefficiency eingeführt hat, sondern auch einen Fehler.

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 

Es sollte geschrieben wurden wie dies in erster Linie:

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 

Leichter zu lesen, effiziente und vermeidet, dass übler Bug.

Auch ich würde viel lieber sehen:

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 

Sie nie die CheckState eines Checkbox verwenden sollten, es sei denn, es Tri-State ist, die vielleicht bei Ihnen sind, aber ich bezweifle es. Wie für Format, sind wir nicht mehr in VB6 Toto.

Verwandte Themen