Search code examples
c#.netobjectdata-access-layer

Programming Objects Advice


I know this is a loaded question and could have many, many answers, but.....I'm creating a small application to be used by myself and a few other friends for now and if it more people like it, I will distribute it to them. It's a simple app for tracking clients for fitness people. It will track clients, payments, payment history, schedule, files (photos, emails, etc.) and maybe a tad more but overall a very simple program. Oh yeah, using SQLExpress as the back-end. My question is this: What is the best approach to designing the objects that are needed for this app? I've read articles about Data access layers and business objects but have never truely created one from scratch. I was thinking of having objects like Client, Payment, etc. and of course all the properties that go with them but when it comes to modifying the DB, should the add, update, delete, etc. methods go in the object or would they reside in the DAL with the object just passing in the stored procedure name?

I know there's lots of info probably missing but hopefully you can get the gist (sp?) of what I am trying to do.

** to respond to some of the posts:

I agree with having the object be seperate of the dal but I will need to read more on how to design it this way...again, new to OO programming so I can't quite see the whole picture.

Here's a DAL that a friend made and has let me use it:

namespace DataAccess{
public class SQLDataBase
{
    public SQLDataBase();
    public SQLDataBase(string EncodedConnectionString);
    public SQLDataBase(string EncodedConnectionString, int ConnectionTimeout);

    public string ConnectionString { get; set; }
    public int ConnectionTimeout { get; set; }
    public string EncodedConnectionString { get; }

    public void RunSpGetScaler(string spName, SqlParameter[] parms, ref DateTime ReturnValue);
    public void RunSpGetScaler(string spName, SqlParameter[] parms, ref decimal ReturnValue);
    public void RunSpGetScaler(string spName, SqlParameter[] parms, ref int ReturnValue);
    public void RunSpGetScaler(string spName, SqlParameter[] parms, ref string ReturnValue);
    public DataSet RunSpReturnDS(string DatasetName, string spName);
    public DataSet RunSpReturnDS(string DatasetName, string spName, SqlParameter[] parms);
    public int RunSpReturnRecordCount(string spName);
    public int RunSpReturnRecordCount(string spName, SqlParameter[] parms);
    public string RunSpReturnString(string spName, SqlParameter[] parms, string returnParm);
    public SqlConnection RunSqlConnection();
}

}

pretty simple...the only issue I have with it is when I create any objects to use it, I have to write methods for every call I make to the DB....so for instance:

   //Declarations - which I don't thinkk should be in the object itself
    private DataAccess.SQLDataBase oDatabase = null;
    private string sEncodedConnectionString = app.Default.EncodedDBString;
    private int iConnectionTimeout = 15;

    public DataSet GetClientInformation(int iClinetID, string sClientName)
    {
        oDatabase = new SQLDataBase(
            sEncodedConnectionString, iConnectionTimeout);

        string spName = "GetClientInformation";
        string dsName = "GetClientInformation";

        try
        {
            SqlParameter[] Params = new SqlParameter[2];
            Params[0] = new SqlParameter("@ClientID", iClientID);
            Params[1] = new SqlParameter("@ClientName", sClientName);

            DataSet ds = oDatabase.RunSpReturnDS(dsName, spName, Params);
            return ds;
        }
        catch (Exception e)
        {
            throw (e);
        }
    }

So for my client object, I've got this and several other methods for adding, modifying, or selecting data for a "client". Logically, this doesn't make sense to me because it seems I wouldn't be able to use this without having to have a few other dependencies with it.


Solution

  • Creating separate layers allow your application to separate concerns. The UI (and other hosts) access an object oriented model that's easy to consume without knowing anything about how the data is stored. In patterns like MVC you can even have a controller layer that mediates between the views and the model. Another very good pattern to look into.

    The object model uses the data access layer and has no direct knowledge of how the data is stored and retrieved. The data access layer may be a little bit flatter and more focused on being able to access and write data efficiently. The public object model layer needs to be a nice object oriented layer that you can potentially maintain compat on.

    Other reasons for layers:

    • Minimize churn on changes: You can swap out how you store while impacting the least number of layers, subsystems and code as possible.
    • Testing: You can mock complete layers to unit test high layers.
    • Decouple Implementation: You can start with a simple layer (like files etc...) while your waiting on some else (or future development) for that other layer.