I don’t understand why people forget they are in an object oriented language when it comes to the data access code. You should not be writing the same code over and over again. First, you should have a base class that is used in all of your projects. This base class should take care of the connection string, logging exceptions, etc. I wrote one years ago and haven’t changed it much since.
Look at the following for samples that would be in this base class:
protected SqlCommand GetNewCmd()
{
SqlCommand objCmd = new SqlCommand();
objCmd.Connection = new SqlConnection(this.ConnString);
objCmd.CommandType = CommandType.StoredProcedure;
return objCmd;
}
protected SqlCommand GetNewCmd(string CmdText)
{
SqlCommand objCmd = new SqlCommand(CmdText,
new SqlConnection(this.ConnString));
objCmd.CommandType = CommandType.StoredProcedure;
return objCmd;
}
protected DataTable GetTable(SqlCommand objCmd)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
try
{
da.SelectCommand = objCmd;
da.Fill(dt);
dt.DefaultView.AllowNew = false;
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
Close(objCmd);
da.Dispose();
da = null;
}
return dt;
}
We have GetTable(), GetDataSet(), ExecuteScalarInt(), ExecuteScalarGuid(), etc. and a bunch of overloads for each.
So these are in my base class and I inherit from this class to do my project specific work. But now this is greatly simplified like these examples:
public DataTable GetStages(int id)
{
SqlCommand cmd = GetNewCmd("dbo.GetStages");
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
return GetTable(cmd);
}
public void DeleteStage(int id)
{
SqlCommand cmd = GetNewCmd("dbo.DeleteStage");
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
ExecuteNonQuery(cmd);
}
As a side benefit, I can script out this code based on the stored proc. Here is the code to do that. So it saves me a lot of typing especially when there are a lot of parameters.
Finally, using other object oriented techniques I get my code down to the following:
GridView1.DataSource = cApp.DB.GetStages(id);
GridView1.DataBind();
(Most of the time there is a business object in the middle of that, but you get the idea.)
All the connection string, exception logging, etc is encapsulated in that 1 line.
Another side benefit is that your base class can get way more involved then you ever would if you are copying code every time. For example, we log exceptions to a database table. Only if that fails does it then log it to a text file. This extensive logic is fine if it lives in one place in the base class, but its not something you are going to want to copy and paste all over your project.
This also make it easy to incorporated some best practices such as opening the connection as late as possible and closing it as soon as possible.