Link to home
Start Free TrialLog in
Avatar of cindyrod
cindyrod

asked on

How to efficiently use classes in an ASP.NET application using C#

I'm learning ASP.NET using C#. I have learned most of the basic stuff and I can create a simple application. I want to be able to create my own classes and namespaces so that I can load data from a database into them because that's how I see it done in the ASP.NET Starter Kits, so I thought that was the best way to go when developing my application. I have no idea on how to incorporate objects with a database. For instance, if I have a table called "Projects" in the database, with fields for project name, start date, end date, contact person, etc., would I be able to store that information into an object and use it there? How would that benefit the application in terms of performance? Is there any good tutorial on this? I have tried searching for it, but I haven't found a good tutorial. I read the whole SitePoint book (Build your own ASP.NET website using C# and VB.NET) and the author didn't mention anything about creating custom objects to use the data from a database.

What I want to do (I think) is to store the data from the database in an object, use it any way I want it, and then update the data in the database. Is that how it works? Maybe I'm just really, really, really confused about the whole process. Any links, info, and suggestions will be appreciated, as I'm completely lost here.

In summary, I want to learn how to use classes in an efficient way in an ASP.NET application, how to create them (declarations), and how to organize them. I'm using Visual Studio .NET 2003.

Thanks in advance,
Cindy
ASKER CERTIFIED SOLUTION
Avatar of brdrok
brdrok

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cindyrod
cindyrod

ASKER

brdrok,

Thank you for your input. How do I create a namespace in C#? Would it be a .cs file? How do I organize the folders for the business layer? For instance, can I create a folder called BusinessLayer and put all of my .cs files in there? How do I create the BusinessLayer and DataLayer namespaces?

I know this is probably very simple, but I just started learning ASP.NET two weeks ago.

Thanks again.
to create a namespace...

namespace yournamesapce
{
    public class MyClassName
    {

     }
}

if you create a folder, it will create a namespace automatically I believe.  So for example, you have a soltuion called "MySolution" and then you create a folder called "MyFolder" and then you add a class called "MyClass", then the namespace for the class "MyClass" is:

MySolution.MyFolder

assuming you put that class in that same folder.

Many different ways to skin the same cat...but I suppose the best way I think is to create seperate projects just for your Data Layer and another project just for your business layer.  If you like, you always can import those projects into the same solution.

General rule of thumb is that your *.cs file should be the same name as your class name.  

Hope that I answered some of your questions...
Thank you so much for your help.

So, if I create a class called "Project" in a file called "Project.cs" then I can use it in my solution by including the namespace at the top of the code using the "using" clause, like this:

using MySolution.MyNamespace

More questions:
How do I use a database and object-oriented programming together? That is, do I populate an object with data from a database or viceversa? How do the Business Logic Layer and the Data Access Layer work together?
I think perhaps sample code would probably answer most of your questions....


using System;
using System.Data;
using SWOLDAL;   //import the namespace responsible for database access
using System.Collections;

namespace SWOLBL
{
      /// <summary>
      /// Collection class containing Cost Center objects
      /// </summary>
      public class CostCenterCollection : CollectionBase
      {
                //maintains a reference to my dataset
            private DataSet m_ds;

            public CostCenterCollection()
            {}

                //when clients call this method, it will create an instance of my data layer access class and then I loop through my dataSet and create individual "CostCenter" objects and add it to my list
            public void GetAllCostCenters()
            {
                  SWOLDAL.CostCenterData myData = (m_ds == null) ? new CostCenterData() : new CostCenterData(m_ds);
                  m_ds = myData.GetAllCostCenters();

                  foreach (DataRow dr in m_ds.Tables["tblCostCenters"].Rows)
                  {
                        this.Add(new CostCenter(this, dr));
                  }
            }

            public void Add(CostCenter newCostCenter)
            {
                  this.List.Add(newCostCenter);
            }

            public void Remove(CostCenter oldCostCenter)
            {
                  this.List.Remove(oldCostCenter);
            }

            public CostCenter this[int index]
            {
                  get {  return (CostCenter) this.List[index]; }
            }

            public DataSet Persist()
            {
                  if (m_ds.HasChanges())
                  {
                        DataSet dsChanges = m_ds.GetChanges();
                        if (dsChanges.Tables["tblCostCenters"].Rows.Count > 0)
                        {
                              SWOLDAL.OrderViewData myData = new OrderViewData();
                              myData.Update(m_ds);
                              if (m_ds.HasErrors)
                              {
                                    m_ds.Merge(dsChanges);
                              }
                              else
                              {
                                    dsChanges.AcceptChanges();
                                    m_ds.Merge(dsChanges);
                                    return m_ds;
                              }
                        }
                  }
                  return m_ds;
            }
      }
}

below this line is the code for the individual "Cost Center" objects:

using System;
using SWOLDAL;
using System.Data;

namespace SWOLBL
{
      /// <summary>
      /// Summary description for Class1.
      /// </summary>
      public class CostCenter
      {
            private DataRow                                          m_dr; //responsible for filling in property value
            private CostCenterCollection                  m_parent; //reference back to parent
            private ProjectCollection                        m_projectCol;  //ignore for now

                //constructor...and pass a reference to the parent if you will, and use the DataRow to expose values for the properties.  Once you see it below...it should be pretty self-evident.
            public CostCenter(CostCenterCollection col, DataRow dr)
            {
                  m_parent = col;
                  m_dr = dr;
            }

            #region Properties

            public string ID
            {
                  get
                  {
                        if (m_dr["ID"] != DBNull.Value)
                              return m_dr["ID"].ToString();
                        else
                              return "";
                  }
                  set
                  {
                        m_dr["ID"] = value;
                  }
            }

            public string Name
            {
                  get
                  {
                        if (m_dr["Name"] != DBNull.Value)
                              return m_dr["Name"].ToString();
                        else
                              return "";
                  }
                  set
                  {
                        m_dr["Name"] = value;
                  }
            }

                //dunno if this is the best way to stick a collection object as a property but it works for now but you might wanna ignore this for now.
            public ProjectCollection Projects
            {
                  get
                  {
                        if (m_projectCol == null)
                        {
                              m_projectCol = new ProjectCollection();
                              m_projectCol.GetAllProjectsBasedOnCostCenterID(this.ID);
                              return m_projectCol;
                        }
                        else
                        {
                              return m_projectCol;
                        }
                  }
            }
            #endregion

                //delete the dataRow, and remove itself from the collection object
            public void Delete()
            {
                  m_dr.Delete();
                  this.m_parent.Remove(this);
            }
      }
}



Finally, somewhere in your code...you could have code something like that

//create an instance
CostCenterCollection myCol = new CostCenterCollection()
//fill the collection object with objects of type CostCenter
myCol.GetAllCostCenters();

assuming you already have a dataGrid called dataGrid1, you could do something like the following:

dataGrid1.DataSource = myCol;
dataGrid1.DataBind();

anyways....hope this is somewhat clear...if not...i'll try to answer...


hth
ooppsss....forgot something....here is the code that handles database stuff

using System;
using System.Data;
using System.Data.OleDb;

namespace SWOLDAL
{
      /// <summary>
      /// Collection class containing instances of cost center objects
      /// </summary>
      public class CostCenterData : AccessLayer
      {
            private OleDbDataAdapter      m_daCostCenter;
            private OleDbCommand            m_cmdCostCenterInsert,
                                                      m_cmdCostCenterUpdate,
                                                      m_cmdCostCenterDelete;

            public CostCenterData() : base() {}
            public CostCenterData(DataSet ds) : base(ds) {}
            public CostCenterData(OleDbConnection cn) : base(cn) {}
            public CostCenterData(DataSet ds, OleDbConnection cn) : base(ds, cn) {}

            public DataSet GetAllCostCenters()
            {
                  OleDbCommand cmdCostCenter = new OleDbCommand();
                  cmdCostCenter.CommandText = "usp_CostCentersSelect";
                  cmdCostCenter.CommandType = CommandType.StoredProcedure;
                  cmdCostCenter.Connection = m_cn;
                  
                  m_daCostCenter = new OleDbDataAdapter();
                  m_daCostCenter.SelectCommand = cmdCostCenter;

                  try
                  {
                        m_daCostCenter.Fill(m_ds, "tblCostCenters");
                  }
                  catch(Exception ex)
                  {
                        string err = ex.Message;
                  }
                  return m_ds;
            }

            private void PrepareDataAdapters()
            {
                  m_daCostCenter = new OleDbDataAdapter();

                  m_cmdCostCenterUpdate = new OleDbCommand();
                  m_cmdCostCenterUpdate.CommandText = "[usp_OrderViewUpdate]";
                  m_cmdCostCenterUpdate.CommandType = CommandType.StoredProcedure;
                  m_cmdCostCenterUpdate.Connection = m_cn;
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("intPositionID", OleDbType.Integer, 4, "PositionID"));
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strPositionName", OleDbType.VarChar, 255, "PositionName"));
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strJobDescription", OleDbType.VarChar, 255, "JobDescription"));
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strJobRequirement", OleDbType.VarChar, 255, "JobRequirement"));
                  m_daCostCenter.UpdateCommand = m_cmdCostCenterUpdate;

                  m_cmdCostCenterInsert = new OleDbCommand();
                  m_cmdCostCenterInsert.CommandText = "[usp_CostCenterInsert]";
                  m_cmdCostCenterInsert.CommandType = CommandType.StoredProcedure;
                  m_cmdCostCenterInsert.Connection = m_cn;
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strPositionName", OleDbType.VarChar, 255, "PositionName"));
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strJobDescription", OleDbType.VarChar, 255, "JobDescription"));
                  m_cmdCostCenterUpdate.Parameters.Add(new OleDbParameter("strJobRequirement", OleDbType.VarChar, 255, "JobRequirement"));
                  m_daCostCenter.InsertCommand = m_cmdCostCenterInsert;

                  //DeleteCommand
                  m_cmdCostCenterDelete = new OleDbCommand();
                  m_cmdCostCenterDelete.CommandText = "[usp_CostCenterDelete]";
                  m_cmdCostCenterDelete.CommandType = CommandType.StoredProcedure;
                  m_cmdCostCenterDelete.Connection = m_cn;
                  m_cmdCostCenterDelete.Parameters.Add(new OleDbParameter("intCostCenterID", OleDbType.Integer, 4, "PositionID"));
                  m_daCostCenter.DeleteCommand = m_cmdCostCenterDelete;
            }

            public DataSet Update(DataSet ds)
            {
                  PrepareDataAdapters();

                  m_daCostCenter.ContinueUpdateOnError = true;

                  try
                  {
                        m_daCostCenter.Update(ds, "tblCostCenters");
                  }
                  catch(OleDbException ex)
                  {
                                //TODO: probably might wanna have your own exception class or whatever....don't have time
                        string err = ex.Message;
                  }
                  return ds;
            }
      }
}


CostCenterData class is inheriting from AccessLayer class which looks like the following.  The AccessLayer is primarily responsible for handling the connection to the database.

using System;
using System.Data;
using System.Data.OleDb;

namespace SWOLDAL
{
      /// <summary>
      /// Summary description for AccessLayer.
      /// </summary>
      public class AccessLayer : DataLayerBase
      {
            protected System.Data.OleDb.OleDbConnection            m_cn;

            public AccessLayer() : base()
            {
                  this.SetupConnection();
            }

            public AccessLayer(DataSet ds) : base(ds)
            {
                  this.SetupConnection();
            }

            public AccessLayer(DataSet ds, OleDbConnection cn) : base(ds)
            {
                  this.SetupConnection();
                  m_cn = cn;
            }

            public AccessLayer(OleDbConnection cn) : base()
            {
                  this.SetupConnection();
                  m_cn = cn;
            }

            private void SetupConnection()
            {
                  m_cn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\Toll Apps DEV\SWOLNet\SWOL2000.mdb; Persist Security Info = False");
            }
      }
}


As you may have seen, AccessLayer inherits from DataLayerBase which is responsible for setting up the dataset.

using System;
using System.Data.OleDb;
using System.IO;
using System.Reflection;
using System.Data;

namespace SWOLDAL
{
      /// <summary>
      /// Base class for Data Layer
      /// </summary>
      public class DataLayerBase
      {
            protected DataSet            m_ds;

            public DataLayerBase()
            {
                  m_ds = new DataSet();

                  Assembly assem = Assembly.GetExecutingAssembly();
                  Stream strm = assem.GetManifestResourceStream("SWOLDBSchema.xsd");

                  try
                  {
                        m_ds.ReadXmlSchema(strm);
                  }
                  catch(Exception ex)
                  {
                        string err = ex.Message;
                  }
            }

            public DataLayerBase(DataSet ds)
            {
                  m_ds = ds;
            }
      }
}

anyways...i believe that I got all the code to get you jump started   =)

hth