The code to posted to populate a DataTable seems wrong to me as ExecuteNonQuery() returns an int so it can't be cast to a DataTable anyway.
The way I do it is to use a SqlDataAdapter to fill a table.
Here's code that compiles - but don't use it as this is not going to work:
public DataTable UsingDataTable()
{
using (SqlConnection connection = new SqlConnection("DBConection"))
{
using (SqlCommand cmd = new SqlCommand("SPNAME", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
da.Fill(dt);
return dt;
}
}
}
}
}
You can't return a DataTable that you are disposing at the same time it returns. The calling code needs to be able to work with it before it is disposed.
So the way to do that is to inject the code that uses the DataTable into the method so that it can be executed before it returns. Try this:
public void UsingDataTable(Action<DataTable> action)
{
using (SqlConnection connection = new SqlConnection("DBConection"))
{
using (SqlCommand cmd = new SqlCommand("SPNAME", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
a.Fill(dt);
action(dt);
}
}
}
}
}
Now you can call that like this:
UsingDataTable(dt => Console.WriteLine(dt.Rows[0][0].ToString()));