3
\$\begingroup\$

Is there a cleaner way of checking a dataset for tables/rows before attempting to read them?

If ds.Tables.Count > 0 Then
    If ds.Tables(0).Rows.Count > 0 Then

        'do something with the the rows at this point

    End If
End If

Edit to clarify - I am talking specifically about the two bool checks to see if the dataset acutally contains any data in table(0).

\$\endgroup\$
  • 1
    \$\begingroup\$ Please define: Check? Do you want to check for the existence of columns or that a value was returned? \$\endgroup\$ – Bobby Dec 15 '11 at 10:12
5
\$\begingroup\$

Assuming that you are using a version of .NET that supports extension methods you could write an extension which does the basic check.

VB.NET

Public NotInheritable Class DataSetExtensions
    Private Sub New()
    End Sub
    <System.Runtime.CompilerServices.Extension> _
    Public Shared Function IsTableDataPopulated(dataSet As DataSet) As Boolean
        Return dataSet IsNot Nothing AndAlso dataSet.Tables.Count > 0 AndAlso dataSet.Tables(0).Rows.Count > 0
    End Function
End Class

c#

public static class DataSetExtensions
{
    public static bool IsTableDataPopulated(this DataSet dataSet)
    {
        return dataSet != null && dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0;
    }
}

Usage

if (ds.IsTableDataPopulated()) 
{
   // do stuff
}

Note: I am not 100% sure if the VB code works as I used a translator for converting c# to VB.NET, call me lazy :)

\$\endgroup\$
5
\$\begingroup\$

I'm doing a couple of assumptions here, but I hope I'm on target.

If you just want the first column of the first row, you should use SqlCommand.ExecuteScalar instead of reading it into a dataset.

For instance:

using (var cn = new SqlConnection("..."))
{
    using (var cmd = new SqlCommand("SELECT statusCode FROM table WHERE whatever", cn)
    {
        cn.Open();
        return (string)cmd.ExecuteScalar();
    }
}

(Notice the using statement if you don't know it. It automatically disposes the connection and command)

You could also look into using SqlCommand.ExecuteReader which returns an SqlDataReader. The latter is cleaner and has better performance than the dataset method too.

using (var reader = cmd.ExecuteReader())
{
    while(reader.Read()) 
    { 
        var value = reader.GetString(0); 
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ The reader needs to be disposed, too. \$\endgroup\$ – Bobby Dec 15 '11 at 10:12
5
\$\begingroup\$

This looks like a good opportunity to use AndAlso.

From the MSDN documentation (http://msdn.microsoft.com/en-us/library/cb8x3kfz(v=vs.80).aspx):

One use of the AndAlso operator is to test for the existence of an object instance before attempting to access one of its members.

In your case:

If ds.Tables.Count > 0 AndAlso ds.Tables(0).Rows.Count > 0 Then

(Which is basically what Kane said, without the funky extension methoding - now that I re-read his answer)

\$\endgroup\$
0
\$\begingroup\$
    Dim ds As New DataSet
    Dim bExists As Boolean
    Try
        bExists = ds.Tables(0).Rows.Count > 0
    Catch
        'There is no rows or either the Dataset or DataTable are nothing/null
    End Try

    If bExists Then
        '... Do your task
    End If

bExists will be True if the DataSet and DataTable are not nothing and the DataTable has rows. If one of them is nothing an Object reference exception will occur and the bExists remains False, also if they are not nothing but the table has no rows then the bExists will be false.

\$\endgroup\$
  • \$\begingroup\$ could you explain this answer a little bit please? \$\endgroup\$ – Malachi Apr 12 '14 at 14:34
  • \$\begingroup\$ "bExists" will be True if the DataSet and DataTable are not nothing and the DataTable has rows. If one of them is nothing an Object reference exception will occure and the bExists remains False, also if they are not nothing but the table has no rows then the bExists will be false. \$\endgroup\$ – Deja Vu Apr 12 '14 at 14:45
  • \$\begingroup\$ Or something else caused an exception in the try block and you just ate an exception. Note that whether this matters, depends upon what else is done in your try block. But for just that reason, you shouldn't use try/catch as a substitute for appropriate validation. \$\endgroup\$ – jmoreno Apr 12 '14 at 19:39
  • \$\begingroup\$ How come that! Could you provide me an exception will occure except the object reference? and this solution is especially made for this case, the try block just validate the expression. It's valid way to check and it's used inside the .NET Framework if tried to refactor some of it's code! for example: "TryCast" \$\endgroup\$ – Deja Vu Apr 12 '14 at 19:49
  • \$\begingroup\$ Generally, this type of thing should be avoided unless there is no other way to do it. It is much cheaper, and less error prone to simply check for the conditions you know can go wrong, rather than to rely on exceptions. \$\endgroup\$ – Mitchell Lee Apr 12 '14 at 23:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.