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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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...
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...
ASKER
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?
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["tblCostCenter s"].Rows)
{
this.Add(new CostCenter(this, dr));
}
}
public void Add(CostCenter newCostCenter)
{
this.List.Add(newCostCente r);
}
public void Remove(CostCenter oldCostCenter)
{
this.List.Remove(oldCostCe nter);
}
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["tblCost Centers"]. 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(CostCenterColle ction 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.GetAllProject sBasedOnCo stCenterID (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
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["tblCostCenter
{
this.Add(new CostCenter(this, dr));
}
}
public void Add(CostCenter newCostCenter)
{
this.List.Add(newCostCente
}
public void Remove(CostCenter oldCostCenter)
{
this.List.Remove(oldCostCe
}
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["tblCost
{
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(CostCenterColle
{
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.GetAllProject
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(OleDbConnec tion 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.StoredProcedur e;
cmdCostCenter.Connection = m_cn;
m_daCostCenter = new OleDbDataAdapter();
m_daCostCenter.SelectComma nd = 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.Comm andText = "[usp_OrderViewUpdate]";
m_cmdCostCenterUpdate.Comm andType = CommandType.StoredProcedur e;
m_cmdCostCenterUpdate.Conn ection = m_cn;
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("intPositio nID", OleDbType.Integer, 4, "PositionID"));
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strPositio nName", OleDbType.VarChar, 255, "PositionName"));
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strJobDesc ription", OleDbType.VarChar, 255, "JobDescription"));
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strJobRequ irement", OleDbType.VarChar, 255, "JobRequirement"));
m_daCostCenter.UpdateComma nd = m_cmdCostCenterUpdate;
m_cmdCostCenterInsert = new OleDbCommand();
m_cmdCostCenterInsert.Comm andText = "[usp_CostCenterInsert]";
m_cmdCostCenterInsert.Comm andType = CommandType.StoredProcedur e;
m_cmdCostCenterInsert.Conn ection = m_cn;
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strPositio nName", OleDbType.VarChar, 255, "PositionName"));
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strJobDesc ription", OleDbType.VarChar, 255, "JobDescription"));
m_cmdCostCenterUpdate.Para meters.Add (new OleDbParameter("strJobRequ irement", OleDbType.VarChar, 255, "JobRequirement"));
m_daCostCenter.InsertComma nd = m_cmdCostCenterInsert;
//DeleteCommand
m_cmdCostCenterDelete = new OleDbCommand();
m_cmdCostCenterDelete.Comm andText = "[usp_CostCenterDelete]";
m_cmdCostCenterDelete.Comm andType = CommandType.StoredProcedur e;
m_cmdCostCenterDelete.Conn ection = m_cn;
m_cmdCostCenterDelete.Para meters.Add (new OleDbParameter("intCostCen terID", OleDbType.Integer, 4, "PositionID"));
m_daCostCenter.DeleteComma nd = m_cmdCostCenterDelete;
}
public DataSet Update(DataSet ds)
{
PrepareDataAdapters();
m_daCostCenter.ContinueUpd ateOnError = 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.OleDbCon nection 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(OleDbConnectio n 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.GetExecutingAssem bly();
Stream strm = assem.GetManifestResourceS tream("SWO LDBSchema. 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
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(OleDbConnec
public CostCenterData(DataSet ds, OleDbConnection cn) : base(ds, cn) {}
public DataSet GetAllCostCenters()
{
OleDbCommand cmdCostCenter = new OleDbCommand();
cmdCostCenter.CommandText = "usp_CostCentersSelect";
cmdCostCenter.CommandType = CommandType.StoredProcedur
cmdCostCenter.Connection = m_cn;
m_daCostCenter = new OleDbDataAdapter();
m_daCostCenter.SelectComma
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.Comm
m_cmdCostCenterUpdate.Comm
m_cmdCostCenterUpdate.Conn
m_cmdCostCenterUpdate.Para
m_cmdCostCenterUpdate.Para
m_cmdCostCenterUpdate.Para
m_cmdCostCenterUpdate.Para
m_daCostCenter.UpdateComma
m_cmdCostCenterInsert = new OleDbCommand();
m_cmdCostCenterInsert.Comm
m_cmdCostCenterInsert.Comm
m_cmdCostCenterInsert.Conn
m_cmdCostCenterUpdate.Para
m_cmdCostCenterUpdate.Para
m_cmdCostCenterUpdate.Para
m_daCostCenter.InsertComma
//DeleteCommand
m_cmdCostCenterDelete = new OleDbCommand();
m_cmdCostCenterDelete.Comm
m_cmdCostCenterDelete.Comm
m_cmdCostCenterDelete.Conn
m_cmdCostCenterDelete.Para
m_daCostCenter.DeleteComma
}
public DataSet Update(DataSet ds)
{
PrepareDataAdapters();
m_daCostCenter.ContinueUpd
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.OleDbCon
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(OleDbConnectio
{
this.SetupConnection();
m_cn = cn;
}
private void SetupConnection()
{
m_cn = new OleDbConnection(@"Provider
}
}
}
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.GetExecutingAssem
Stream strm = assem.GetManifestResourceS
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
ASKER
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.