Thursday, June 3, 2010

How to create Data Access Layer in ASP.NET using C#

Data Access Layer or DAL in my code can be used to work with 
different databases if we add all different types of System.Data like System.Data.SqlClient, System.Data.Odbc, System.Data.OleDb but for simplicity I consider only Microsoft SQL Server. You do not need to change the connection configuration line as you can keep the SQLDBConnection as is and only change it in your Web.Config  file

private string
strConnection =
ConfigurationManager.ConnectionStrings["SQLDBConnection"].ConnectionString;

So here is the entire code below

using
System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DataAccessLayer
{
    public sealed class DBManagerFactory
    {
        private DBManagerFactory(){}
        public static SqlConnection GetConnection()
        {
            SqlConnection mySQLDbConnection = null;
            mySQLDbConnection = new SqlConnection();
            return mySQLDbConnection;
        }

        public static SqlCommand GetCommand()
        {
            return new SqlCommand();
        }

        public static SqlDataAdapter GetDataAdapter()
        {
            return new SqlDataAdapter();
        }

        public static SqlTransaction GetTransaction()
        {
            SqlConnection mySQLDbConnection = GetConnection();
            SqlTransaction mySQLTransaction = mySQLDbConnection.BeginTransaction();
            return mySQLTransaction;
        }

        public static SqlParameter GetParameter()
        {
            SqlParameter myStoreProcParameter = null;
            myStoreProcParameter = new SqlParameter();
            return myStoreProcParameter;
        }

        public static SqlParameter[] GetParameters(int paramsCount)
        {
            SqlParameter[] idbParams = new SqlParameter[paramsCount];
          for (int i = 0; i < paramsCount; ++i)
          {
              idbParams[i] = new SqlParameter();
          }
          return idbParams;
        }
    }


    public sealed class SQLDBManager : IDisposable
    {
        private SqlConnection mySQLDbConnection;
        private SqlDataReader  mySQLdataReader;
        private SqlDataAdapter mySQLdataAdapter;
        private SqlCommand mySQLCommand;
        private SqlTransaction mySQLTransaction =null;
        private SqlParameter[]mySQLParameters =null;
        private string strConnection = ConfigurationManager.ConnectionStrings["SQLDBConnection"].ConnectionString;

        public SQLDBManager()
        {
            Open();
        }

        public SQLDBManager(int paramNum)
        {
            Open();
            if (paramNum >= 1)
            { CreateParameters(paramNum); }
        }

        public SqlConnection Connection
        {
            get
            {
                return mySQLDbConnection;
            }
        }

        public SqlDataReader DataReader
        {
            get
            {
                return mySQLdataReader;
            }
            set
            {
                mySQLdataReader = value;
            }
        }

        public SqlDataAdapter DataAdapter
        {
            get
            {
                return mySQLdataAdapter;
            }
            set
            {
                mySQLdataAdapter = value;
            }
        }

        public string ConnectionString
        {
            get
            {
                return strConnection;
            }
            set
            {
                strConnection = value;
            }
        }

        public SqlCommand Command
        {
            get
            {
                return mySQLCommand;
            }
        }

        public SqlTransaction Transaction
        {
            get
            {
                return mySQLTransaction;
            }
        }

        public SqlParameter[] Parameters
        {
            get
            {
                return mySQLParameters;
            }
        }

        public void Open()
        {
            mySQLDbConnection = DBManagerFactory.GetConnection();
            mySQLDbConnection.ConnectionString = this.ConnectionString;
            if (mySQLDbConnection.State != ConnectionState.Open)
                mySQLDbConnection.Open();
            this.mySQLCommand = DBManagerFactory.GetCommand();
        }

        public void Close()
        {
            if (mySQLDbConnection.State != ConnectionState.Closed)
                mySQLDbConnection.Close();
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
            this.Close();
            this.mySQLCommand = null;
            this.mySQLTransaction = null;
            this.mySQLDbConnection = null;
        }

        public void CreateParameters(int paramsCount)
        {
            mySQLParameters = new SqlParameter[paramsCount];
            mySQLParameters = DBManagerFactory.GetParameters(paramsCount);
        }

        public void AddParameters(int index, string paramName, object objValue)
        {
            if (index < mySQLParameters.Length)
            {
                mySQLParameters[index].ParameterName = paramName;
                mySQLParameters[index].Value = objValue;
            }
        }

        public void BeginTransaction()
        {
            if (this.mySQLTransaction == null)
                mySQLTransaction = DBManagerFactory.GetTransaction();
            this.mySQLCommand.Transaction = mySQLTransaction;
        }

        public void CommitTransaction()
        {
            if (this.mySQLTransaction != null)
                this.mySQLTransaction.Commit();
            mySQLTransaction = null;
        }

        public SqlDataReader ExecuteReader(CommandType commandType, string commandText)
        {
            this.mySQLCommand = DBManagerFactory.GetCommand();
            mySQLCommand.Connection = this.Connection;
            PrepareCommand(mySQLCommand, this.Connection, this.Transaction, commandType, commandText, this.Parameters);
            this.DataReader = mySQLCommand.ExecuteReader();
            mySQLCommand.Parameters.Clear();
            return this.DataReader;
        }

        public void CloseReader()
        {
          if (this.DataReader != null)
            this.DataReader.Close();
        }

        private void AttachParameters(SqlCommand command, SqlParameter[]commandParameters)
        {
            foreach (SqlParameter idbParameter in commandParameters)
            {
                if ((idbParameter.Direction == ParameterDirection.InputOutput) && (idbParameter.Value == null))
                {
                    idbParameter.Value = DBNull.Value;
                }
                command.Parameters.Add(idbParameter);
            }
        }

        private void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[]commandParameters)
        {
            command.Connection = connection;
            command.CommandText = commandText;
            command.CommandType = commandType;

            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            if (commandParameters != null)
            {
                AttachParameters(command, commandParameters);
            }
        }

        public int ExecuteNonQuery(CommandType commandType, string commandText)
        {
            this.mySQLCommand = DBManagerFactory.GetCommand();
            PrepareCommand(mySQLCommand, this.Connection, this.Transaction, commandType, commandText, this.Parameters);
            int returnValue = mySQLCommand.ExecuteNonQuery();
            mySQLCommand.Parameters.Clear();
            Dispose();
            return returnValue;
        }

        public object ExecuteScalar(CommandType commandType, string commandText)
        {
            this.mySQLCommand = DBManagerFactory.GetCommand();
            PrepareCommand(mySQLCommand, this.Connection, this.Transaction, commandType, commandText, this.Parameters);
            object returnValue = mySQLCommand.ExecuteScalar();
            mySQLCommand.Parameters.Clear();
            Dispose();
            return returnValue;
        }

        public DataSet ExecuteDataSet(CommandType commandType, string commandText, string dsName)
        {
            this.mySQLCommand = DBManagerFactory.GetCommand();
            PrepareCommand(mySQLCommand, this.Connection, this.Transaction, commandType, commandText, this.Parameters);
            SqlDataAdapter dataAdapter = DBManagerFactory.GetDataAdapter();
            dataAdapter.SelectCommand = mySQLCommand;

            DataSet dataSet = new DataSet();
            dataAdapter.Fill(dataSet, dsName);
            mySQLCommand.Parameters.Clear();
            Dispose();
            return dataSet;
        }

    }
}

And now I'll show you an example of how to simply use it in your code

SQLDBManager mySQLdbManager = new SQLDBManager(1);
mySQLdbManager.AddParameters(0, "@RegID", RegID);
DataSet dsPersonalInfo = new DataSet();
dsPersonalInfo = mySQLdbManager.ExecuteDataSet(CommandType.StoredProcedure, "CI_GetPersonalInfo", "Personal");
 
On the first line, I'm calling the overloaded constructor that has one parameter which is the number of parameters used when calling our SQL stored procedure.

On the fourth line, I designed the ExecuteDataSet to assign a name to the newly populated DataSet so I can use it later when retrieving any column value as shown below. 
 
Label1.Text = "welcome " + dsPersonalInfo.Tables["Personal"].Rows[0]["FirstName"]
+ "&nbsp" +
dsPersonalInfo.Tables["Personal"].Rows[0]["LastName"]

Sunday, May 23, 2010

Difference between Application, Session, ViewState and Cache objects

Session has a Session ID which is created for every user so if the user request the web application, then a session ID will be created for this user and if he/she exits from the web application, the Session ID will be lost and a new one will be created if he/she requests the web application again.

While in Application object once the first user requests the web application, the application object will be created and maintained till the last user exits from the web application

ViewState is a technique used in ASP.NET to keep the values or settings applied to ASP.NET Server controls persistant during round trips between client and server.

You can check the ViewState object in the source code of the page, it's encrypted so users can never watch what is really written in there.

It's really recommended to disable unused ViewStates on some of ASP.NET Server controls like Labels by going to any server control and set the EnableViewState property to false

Cache is a technique used in data that takes long times to be retrieved e.g. data that has not been changed and is retrieved from SQL Server database and with Caching data is going to be retrieved from memory.

Just to let you know, caching an object or a page has three restrictions to trigger the server to disregard getting the data from memory and to enforce retrieving the data from the page, it should be used in certain circumstances to ensure that users will get the latest data.

Saturday, May 22, 2010

Tips and Tricks for any ASP.NET developers to study and learn

The reason I write here in my blog, is to document all my experience about ASP.NET tips and tricks, I found it during many interviews I had, actually I didn't count them during my last year of 2009 when I was laid off, I did NOT know how to answer employers' questions on many topics regarding .NET framework, ASP.NET, C#, VB.NET and MS SQL Server 2005 or 2008.

The fact that I really know that all these employers' questions don't mean that I'm not expert in coding .NET desktop and web applications but they don't care they want quick and precise answers to see if they can really hire me or look for someone else.

So I realized that I can write down a couple of questions after every interview and search for quick answers, study them or memorize them if you want the exact term, I figured out that it's about my memory where I began to really feel down because every interview I go there I had been asked the same questions over and over, some of them I succeeded to answer them and some I couldn't so I solved my problem by writing all my thoughts in a word document, then categorize them into different aspects in IT.

Anyway I ended up having a document of more than 250 pages of frequently asked questions during my last hundreds of interviews, well to make the story short, I got a job recently as an ASP.NET Web Application Developer and I know that every programmer they search the internet or use MSDN during their daily coding work but employers they don't really care because they can't decide if you're the right candidate or not within a very short period of time usually it's 30 minutes of time so I decided to write everything in my own style which I really couldn't answer it to help me have a solid knowledge and understanding in the IT field.

I encourage everyone to contribute with questions and programming challenges in the Microsoft world.