http://www.codeproject.com/Articles/493389/Four-ways-of-passing-data-between-layersData passing between layers
Table of contents
- What’s the goal?
- Layers and Tiers are different things
- Data incoming and data outgoing
- Method 1: Non-uniform way of passing
- Problems and benefits with non-uniform way
- Circular dependency problem
- Method 2: Uniform way of passing data (Entity classes)
- Problems and benefits with uniform way
- Method 3: Data Transfer Objects (DTO)
- Problems and benefits with DTO
- Method 4: Hybrid approach (Entity + DTO)
- When to use what?
- Ready made solutions: Entity Framework and LINQ
What’s the goal?
Layered architecture is the most common way of creating software projects because they bring in SOC (Separation of Concern), decoupling, easy understanding of code, etc. In software industry people are pretty clear about the common layers and their responsibility (UI for look and feel, middle layer for business logic, and data access layer for data).
But the biggest confusion or I will say where developers have not come to common standards is the way of passing data between these layers. This article will try to flesh out the various ways of passing data between layers.
Layers and Tiers are different things
I repeat again layers and not tiers. In case you are confused about layers and tiers, the below diagram explains it visually. Layers are more of a logical separation for your code while tiers mean that those layers are deployed in different physical machines. So for now we will keep the scope of this article limited and restricted, or else we need to get into web service, remoting, etc., which will lead to more confusion.
Data incoming and data outgoing
We will be analyzing the passing of data between layers from two perspectives: how the data will come towards the data access layer, and how the data will pass to UI. As you read the article you would understand better why I want two perspectives.
Method 1: Non-uniform way of passing
This is the first way (probably the most common way) of passing data from one layer to another, the non-uniform way. So let’s start from UI to DAL.
Data from the UI to middle tier is passed using getter and setter, below is a sample code for the same.
Customer objCust = new Customer(); objCust.CustomerCode = "c001"; objCust.CustomerName = "Shivprasad";
Further down from the middle tier to the data access layer, data is passed by using comma separation, arrays or some other non-uniform way which makes a developer personally comfortable. In the below code snippet look at the
Add
method and how it’s making a call to the data access layer with input parameters.public class Customer
{
private string _CustomerName = "";
private string _CustomerCode = "";
public string CustomerCode
{
get { return _CustomerCode; }
set { _CustomerCode = value; }
}
public string CustomerName
{
get { return _CustomerName; }
set { _CustomerName = value; }
}
public void Add()
{
CustomerDal obj = new CustomerDal();
obj.Add(_CustomerName,_CustomerCode);
}
}
Below is the data access layer code with two inputs:
CustomerName
and CustomerCode
.public class CustomerDal
{
public bool Add(string CustomerName,string CustomerCode)
{
// Insert data in to DB
}
}
So summarizing for non-uniform way data is passed in the following ways:
- UI to middle tier (setter and getter).
- Middle tier to data access by using comma, inputs, arrays etc.
Now let’s analyze how data will be passed from DAL to UI in the non-uniform method. So let’s start from the UI first.
From UI, data will be pulled in using the middle tier object as shown below.
Customer obj = new Customer();
List<Customer> oCustomers = obj.getCustomers();
From middle tier the data will be pulled from the data access layer using dataset/datatable/XML etc. The most important point to note is the middle tier loops through the dataset and converts it into a strong type object, in this case it’s
Customer
. You can see the getCustomers
function (code is shown below), how it loops through the dataset and fills in a strongly typed list of customers. This is necessary because the UI is referencing strongly typed classes (watch the UI code snippet just above).public class Customer
{
private string _CustomerName = "";
private string _CustomerCode = "";
public string CustomerCode
{
get { return _CustomerCode; }
set { _CustomerCode = value; }
}
public string CustomerName
{
get { return _CustomerName; }
set { _CustomerName = value; }
}
public List<Customer> getCustomers()
{
CustomerDal obj = new CustomerDal();
DataSet ds = obj.getCustomers();
List<Customer> oCustomers = new List<Customer>();
foreach (DataRow orow in ds.Tables[0].Rows)
{
// Fill the list
}
return oCustomers;
}
This conversion also ensures that we maintain the golden rule of tiered layer: “UI should avoid directly referencing data access components like ADO.NET, OLEDB etc. With this if we change our data access methodology later, it’s not replicated on the UI.” You can watch the project of my console UI, it has no references to
System.Data
, very clean, isn’t it?
The final thing is the
CustomerDal
class which just returns the dataset using ADO.NET to pass the same to the middle layer.public class CustomerDal
{
public DataSet getCustomers()
{
// fetch customer records
return new DataSet();
}
}
Summarizing in a non-uniform way the data is moved to UI in the following ways:
- From DAL to middle tier it uses dataset/XML/datareader (personal choices of developers).
- From middle tier it uses strongly typed classes.
Problems and benefits with Non-uniform way
Some of the benefits of non-uniform way:
- It’s simple and easy to implement. In case your data storage and access methods will not change I think this should suffice.
But it has some serious disadvantages.
- Because we do not have a uniform structure, we need to always convert from one format to another as we pass through each layer, which can lead to performance issues for a large number of rows.
- If developers start using their custom way of passing data (like XML), it will lead to increase in complexity.
- If tomorrow you need to change your data access methodology from ADO.NET to OLEDB, you need to change across tiers.
That’s where we can use the uniform way of passing data, i.e., “Entities”.
Circular dependency problem
In case you are wondering why we cannot use the middle tier classes across layers, do not forget, the middle tier is already using DAL. If DAL tries to use the middle tier it will lead to circular dependency.
Method 2: Uniform way of passing data (Entity classes)
The other way of passing data is using the uniform approach using entity classes. Entity classes are nothing but simple classes with SET and GET. It does not have logic. For instance you can see
CustomerEntity
class with customer name and customer code. Now this class is in a separate project called as Entity so that it can be referenced by all layers.public class CustomerEntity
{
protected string _CustomerName = "";
protected string _CustomerCode = "";
public string CustomerCode
{
get { return _CustomerCode; }
set { _CustomerCode = value; }
}
public string CustomerName
{
get { return _CustomerName; }
set { _CustomerName = value; }
}
}
So let’s start with
CustomerDal
first. The DAL returns back a CustomerEntity
collection and also takes in a CustomerEntity
object to add to the database. Please note the data access layer is responsible to convert the output to the CustomerEntity
type object.public class CustomerDal
{
public List<CustomerEntity> getCustomers()
{
// fetch customer records
return new List<CustomerEntity>();
}
public bool Add(CustomerEntity obj)
{
// Insert in to DB
return true;
}
}
The middle tier inherits from the
CustomerEntity
class and adds behavior to the entity class. This class will have all the business rules for the entity. Also note that data is passed to the data access layer in an Entity class format (see the Add
method) and also the data is returned back in entity format (see the getCustomers
method).public class Customer : CustomerEntity
{
public List<CustomerEntity> getCustomers()
{
CustomerDal obj = new CustomerDal();
return obj.getCustomers();
}
public void Add()
{
CustomerDal obj = new CustomerDal();
obj.Add(this);
}
}
Note: Watch the type cast made in “Add” method. I personally love the elegancy and simplicity the way data is passed to the DAL.
Finally the UI is also no different even he talks with the same protocol of entity class structure.
Summarizing, in the uniform method we pass data from one layer to other layer using “Entity” class structure. So either the data is moving in or out it uses entity structure.
Problems and benefits with uniform way
First let’s talk about good things.
- Due to uniform structure, irrespective of which layer you are on, it’s strongly typed and you get the benefit of Visual Studio intellisense. For instance you can see in the below figure, even though I am in the data access layer, I still know which object and properties I am dealing with. So strong types support across layers.
- Due to common structure you need to convert the data only once, i.e., in DAL. So once the DAL converts the data into Entity format structure it can be used without conversion in the below layers, i.e., UI and middle tier.
The only disadvantage which I see is the double loop problem. When we talk about entity classes they normally represent real world object structure.
Now the database is technically optimized, so the structure of the database world is different from that of the real world. For instance it’s very much possible that you have customer name and address are stored in the same table (denormalized tables) so that you can fetch faster. But as soon as these objects come in the real world it's possible we would like to have one to many relationships. Do have a look at the below image.
So in a simple world we would need to write some kind of logic for this transformation.
Below is a simple code extract from a middle tier where you can see there is a double loop, one loop which fills the customer collection and the other which adds the address object as an aggregated object to the customer object.
foreach (DataRow o1 in oCustomers.Tables[0].Rows)
{
obj.Add(new CustomerEntyityAddress()); // Fills customer
foreach (DataRow o in oAddress.Tables[0].Rows)
{
obj[0].Add(new AddressEntity()); // Fills address
}
}
Method 3: Data transfer objects (DTO)
So to overcome the same we can create classes which are more of technical classes only to pass data efficiently across layers.
And because these are technical classes to just pass data around, we do not need to worry if they represent real world objects or not. In other words, we can flatten the class structure to avoid the double loop problem which we talked about previously.
You can see the below code snippet which shows how the
CustomerDTO
class inherits from CustomerEntity
and aggregates the Address
class to create a de-normalized class which is optimized for quick loading and viewing.public class CustomerDTO : CustomerEntity
{
public AddressEntity _Address = new AddressEntity();
}
You can see in the below code snippet how just one loop fills the de-normalized class.
foreach (DataRow o1 in oCustomers.Tables[0].Rows)
{
CustomerDTO o = new CustomerDTO();
o.CustomerCode = o1[0].ToString();
o.CustomerName = o1[1].ToString();
o._Address.Address1 = o1[2].ToString();
o._Address.Address2 = o1[3].ToString();
obj.Add(o);
}
And as usual, the UI can always call the DTO to get data into the UI.
// From Data out
Customer obj = new Customer();
List<CustomerDTO> oCustomers = obj.getCustomers();
Problems and benefits with DTO
The biggest advantage is quick and fast loading due to denormalized structure.
The biggest disadvantage is as these are technical classes which are optimized from a performance perspective, they can violate all rules of OOP and real world representation. So it is best to have a hybrid approach as discussed in the next section.
Method 4: Hybrid approach (Entity + DTO)
On one side Entity classes represent real world objects which follow OOP principles and on the other side DTO represents flattened classes to gain performance. So the best approach would be to take goodies from both worlds.
When data manipulation happens in the system (it can be insert, update, or delete form) we would like to ensure that we have data integrity and objects exposed on the user interface should mimic the real world. So for those scenarios a full blown normalized class structure (Entity) is the way to go.
But if you are looking to pull huge data to be displayed, like some lengthy report, then a denormalized structure / DTO is more suitable. I still remember in of our old projects these classes where termed as “Reporting classes”. The class structure for these classes never depicted real world objects.
When to use what?
- Non-uniform approach: When you think about it, your data access methods will not change too much. In other words if you think your project tomorrow will not have different databases (like Oracle, SQL Server, etc.), this method is great.
- Uniform approach (Entity, DTO, or hybrid): If you think your project will deal with different flavors of databases, this approach becomes mandatory. In other words your DAL does the conversion once but inside the project, you always refer to a common structure without worrying about the database structure.
Ready made solutions: Entity Framework and LINQ
In good old days we used to write these classes manually. I loved how carefully and tenderly I used to create those classes. World has moved ahead and we have awesome frameworks like EF (Entity Framework) and LINQ which can do magic in minutes. This article will not go beyond its scope to teach Entity Framework or LINQ.
But yes, if you understand the flavors of these classes, you can easily create better class structures by using EF or LINQ.
Source code
You can download the source code from here.
***********************************************************************************************************Data Tables vs Business Objects
In my architechture I have (1) User Interface, (2) a project containing Custom Types or business objects, (3) a business logic layer and (4) data access layer. Further more I use stored procedure in database.
As a developer of course my privorities are code reuseability, fast development and quality of work. I have felt that using business object saves development time in the following ways.
1. It allows immplementing business logic through properties
2. They are easy to create in VS 2008
3. They save time of passing seprate parameters to functions and reduce errors that can raised by passing a lot of parameters individually.
But antoher fact I observed is that using Business Objects for filling data from DataReader waste some time as well. Suppose my stored procedure is returing 20 columns. I will have to catch and fill every column individually but if I just start using DataTable just writing one line of code will save me from writing 20 lines of code. I am in team as senior and I felt every one waste some time doing this.
If as a developer we value code reuseability, fast development and quality of work what you say about using DataTable instead of using Business Objects. Another tpositive thing is that in DataTable there are some built in featurs that we may have to do by overself if we go for buliness objects. Using DataTable is also less bulky than Data Set and speedy than Data Adapter.
Please advice me how you see using business object for implemnting logic, busines rules and passing arguments and use data table (typed or may be untyped) to pass data taken from db to different layers and to bind controls. I am using Enter Prize Library DAAB for database communication.
Typically the preferred method is to use custom business objects over any type of ADO.NET object. There are several advantages of business objects and I can list a few of them out here for you:
- Objects have behavior and encapsulate functionality to a specific business purpose. Using basic OOP principals, the importance of separation of concerns and encapsulation are something you can not achieve with a DataTable that just has been populated from a Database. The DataTable has no behavior or meaning, but is just a type to store data.
- Unless you are using something that is strongly typed in ADO.NET, referencing values within a DataTable will cause you to scatter hardcoded fieldname references throughout the application including the UI. Basic tools like Intellisense in VS.NET make developing much easier and less error proned, and will be more difficult to achieve with a DataTable. If the field name ever changes, the hardcoded references are scattered all throughout the application, where with an object, the reference is probably only made in 1 place, and will probably only require changes in a single layer. Look at the code example below:
'Referencing a field in a DataTable Dim LastName As String = dt.rows(0).Items("LastName").ToString() 'Referncing a field in a custom object Dim LastName As String = MyBusniessObject.LastName
- Since the .NET Framework 2.0 we have had the power of Generics and using List(of MyClass) to create powerful lists of objects, which essentially creates a strongly typed list of objects. These by nature implement the interfaces needed for binding most controls, and become quite powerful at all layers of the application. Passing a List(of MyClass) is preferred IMO to passing around a DataTable with raw data. If you have not looked into this before take a look at the following link:
.NET Object Collections Using Generics 101:
- ADO.NET types like DataTables and DataSets can not house business rules nor expose methods of any type like objects do, and therefore the rules end up getting scattered throughout including the UI. This can increase maintenance time and reduce scalability.
Lastly, I think you should look into using Business Objects and object collections like described in the link above as a better architecture. If you want to read some more discussions on this topic check out the following links:
Why should you use business objects in .NET and not DataSets?
Objects vs. DataSets - Is it Really About the Technical Aspects?
DataSets vs. Collections:
Also, for all of these points, realize a DataTable which you use is just a single object which could make up a DataSet (1..n Tables in a DataSet) so the conversations about DataSets vs Objects are applicable as well.
Data Tables vs Business Objects
If you want to learn about how to develop 3-tier architecture application, please go throughhttp://www.dotnetfunda.com/articles/article18.aspx and how to develop 4-tier architecture, please go throughhttp://www.dotnetfunda.com/articles/article18.aspx. To show the use of generics, I have used downloadable source code available for 4-Tier architecure article.
There were discussion earlier and probably now also on whether we should use DataTable or generic List collection class to pass data between layers, you can read throughhttp://weblogs.asp.net/bsimser/archive/2007/04/04/datatable-vs-bindinglist-t.aspx post to learn more about that but now I feel its evident that using Generic list to pass data between layers is the way to go. I personally prefer Genericl List over DataTable as I have seen its beneifts working in different projects.
There are different views on where the actual conversion of data from DataTable or DataReader to list should happen, some suggest to have a separate translation layer that accepts DataTable or DataReader and converts them into the list of desired objects. Normally people do it into Data Access Layer itself and pass the generic list objects to Presentation Layer through Business Layer. In this demonstration, I shall do the same.
Ideally, if you have preferred to use generic list to pass data between differenet layers you should prefer using entity layer (or I have called BO - Business Objects layer as described in the 4-Tier architecture application article referenced above). In this example, I have a Person business object / entity object that have properties related to a person, I am trying to fill into generic list.
Below code is the Data Access Layer code that gets data from database and convert them into generic list collection. Please note that I have used latest version of C# (3.0) that supports var keyword and other features I have used in below code snippets.
In the above code snipeet, I have two method called LoadDataThroughDataReader and LoadDataThroughDataTable. In both method, I have declared a variable
forList<Person> that is filled with the Person records
returned from the database. The
first method LoadDataThroughDataReader use
cmd.ExecuteReader() method to get the SqlDataReader and read through
all the records in the reader and add the Person object into the List. The
second method is slightly different and use DataTable instead of DataReader
to fetch data from database, loop through all the rows of the DataTable
and add Person objects into the list.
You may wonder why these two methods when both are doing the same thing. I prefer using DataReader when I have lesser amount of data from the database and loop through because DataReader expect live connection when it loops through all the records. For large amount of data, it may be a bottleneck for the database to keep the connection alive and loop through. So for large amount of data I prefer to fill the DataTable, close the database connection and then loop through all the records do the required operation.
Once you have your Data Access Layer method ready to return the generic list collection, you can call it through your business layer (My business layer class name isPersonBAL) as follows:
Get solutions of .NET problems with video explanations, .pdf and
source code in .NET How to's.
As I do not have any logic in the Business Layer, so I have simply instantiated the PersonDAL data access layer object and called the respective methods.
Subsequently, this business layer methods can be called from presentation layer as follows:
4-Tier
Architecture in ASP.NET with C#
http://www.dotnetfunda.com/articles/show/18/4-tier-architecture-in-aspnet-with-csharp
DataTable
vs. BindingList<T>
Good Article to under stand alll above concept
http://imar.spaanjaars.com/416/building-layered-web-applications-with-microsoft-aspnet-20-part-1
Data Tables vs Business Objects
Your
kind attention and expert advice is required please, here I want to disucss
using Data Tables instead of Business objects for passing data between layers
and to bind controls (I am not saying DataSet vs BusinessObjects rather
DataTables vs BusinessObjets)
In
my architechture I have (1) User Interface, (2) a project containing Custom
Types or business objects, (3) a business logic layer and (4) data access
layer. Further more I use stored procedure in database.
As a developer of course my privorities are
code reuseability, fast development and quality of work. I have felt that using business object
saves development time in the following ways.
1.
It allows immplementing business logic through properties
2.
They are easy to create in VS 2008
3.
They save time of passing seprate parameters to functions and reduce errors
that can raised by passing a lot of parameters individually.
But
antoher fact I observed is that using Business Objects for filling data from
DataReader waste some time as well. Suppose my stored procedure is returing 20
columns. I will have to catch and fill every column individually but if I just
start using DataTable just writing one line of code will save me from writing
20 lines of code. I am in team as senior and I felt every one waste some time
doing this.
If as a developer we value code reuseability, fast
development and quality of work what
you say about using DataTable instead of using Business Objects. Another
tpositive thing is that in DataTable there are some built in featurs that we
may have to do by overself if we go for buliness objects. Using DataTable is
also less bulky than Data Set and speedy than Data Adapter.
Please
advice me how you see using business object for implemnting logic, busines
rules and passing arguments and use data table (typed or may be untyped) to
pass data taken from db to different layers and to bind controls. I am using
Enter Prize Library DAAB for database communication.
Thanks
in anticipation for your attention, advice and precious time.
Typically
the preferred method is to use custom business objects over any type of
ADO.NET object. There are several advantages of business objects and
I can list a few of them out here for you:
·
Objects have behavior and encapsulate functionality to a
specific business purpose. Using basic OOP principals, the importance of
separation of concerns and encapsulation are something you can not achieve with
a DataTable that just has been populated from a Database. The DataTable
has no behavior or meaning, but is just a type to store data.
·
Unless you are using something that is strongly typed in
ADO.NET, referencing values within a DataTable will cause you to scatter
hardcoded fieldname references throughout the application including the
UI. Basic tools like Intellisense in VS.NET make developing much
easier and less error proned, and will be more difficult to achieve with a
DataTable. If the field name ever changes, the hardcoded references are
scattered all throughout the application, where with an object, the reference
is probably only made in 1 place, and will probably only require changes in a
single layer. Look at the code example below:
'Referencing a field in a DataTable
Dim LastName As String = dt.rows(0).Items("LastName").ToString()
'Referncing a field in a custom object
Dim LastName As String = MyBusniessObject.LastName
·
Since the .NET Framework 2.0 we have had the power of Generics
and using List(of MyClass) to create powerful lists of objects, which
essentially creates a strongly typed list of objects. These by nature
implement the interfaces needed for binding most controls, and become quite
powerful at all layers of the application. Passing a List(of MyClass) is
preferred IMO to passing around a DataTable with raw data. If you have
not looked into this before take a look at the following link:
.NET Object Collections Using Generics 101:
·
ADO.NET types like DataTables and DataSets can not house
business rules nor expose methods of any type like objects do, and therefore
the rules end up getting scattered throughout including the UI. This can
increase maintenance time and reduce scalability.
Lastly,
I think you should look into using Business Objects and object collections like
described in the link above as a better architecture. If you want to read
some more discussions on this topic check out the following links:
Why should you use business objects in .NET
and not DataSets?
Objects vs. DataSets - Is it Really About the
Technical Aspects?
DataSets vs. Collections:
Also,
for all of these points, realize a DataTable which you use is just a single
object which could make up a DataSet (1..n Tables in a DataSet) so the
conversations about DataSets vs Objects are applicable as well.
·
DTO / Business Objects (BO)
They are Plain Old CLR Object (POCO) that usually contains no logic (or
maybe minimum to convert a DTO in BO, to override compare or toString methods).
For example if you are creating a new
employee, you have a class called EmployeeBO to help transfer data. User
Interface captures data from a form, create a BO, and then sends this BO to
BLL(Business Logic Layer). This BLL does whatever he thinks is needed and
eventually sent BO to Data Access Layer that persist it in DB.
Using BO in BLL Layer helps because you are
dealing with real objects here, you can store them in Lists, Dictionaries...
you can use LINQ to access it, even eventually have an ORM framework or
Microsoft Entity Framework.
·
DataSets
Similar to previous one. Its advantage it is
the main disadvantage. It is highly coupled with db. Don't use it.
·
DataReader
If you ever consider using DataReaders, go
for DataSets :-)
·
Parameters
You pass all parameters
way down from IU layer to BLL and DAL. This is not practical.
The best one are DTOs/Business Objects. Ideally
use a DTO to communicate from UI layer to BLL and make BLL to use their own BO
objects. If you fail to do so (I did), then your UI is coupled with Data Access
Layer making changes in backend complicated. Splitting it between DTOs and BOs
give you the advantage of not being coupled. Usually you have a method
somewhere that converts a DTO into its BO.
Passing data between layers using
Generic list collection
http://www.dotnetfunda.com/articles/show/472/passing-data-between-layers-using-generic-list-collection
This
article is for beginners who want to know how to use .NET generics to pass data
between different layers. If you do not know about generic list, please go
thorugh this article http://www.dotnetfunda.com/articles/article152.aspx.
In brief, List class is a generic equivalent of
ArrayList class.If you want to learn about how to develop 3-tier architecture application, please go throughhttp://www.dotnetfunda.com/articles/article18.aspx and how to develop 4-tier architecture, please go throughhttp://www.dotnetfunda.com/articles/article18.aspx. To show the use of generics, I have used downloadable source code available for 4-Tier architecure article.
There were discussion earlier and probably now also on whether we should use DataTable or generic List collection class to pass data between layers, you can read throughhttp://weblogs.asp.net/bsimser/archive/2007/04/04/datatable-vs-bindinglist-t.aspx post to learn more about that but now I feel its evident that using Generic list to pass data between layers is the way to go. I personally prefer Genericl List over DataTable as I have seen its beneifts working in different projects.
There are different views on where the actual conversion of data from DataTable or DataReader to list should happen, some suggest to have a separate translation layer that accepts DataTable or DataReader and converts them into the list of desired objects. Normally people do it into Data Access Layer itself and pass the generic list objects to Presentation Layer through Business Layer. In this demonstration, I shall do the same.
Ideally, if you have preferred to use generic list to pass data between differenet layers you should prefer using entity layer (or I have called BO - Business Objects layer as described in the 4-Tier architecture application article referenced above). In this example, I have a Person business object / entity object that have properties related to a person, I am trying to fill into generic list.
Below code is the Data Access Layer code that gets data from database and convert them into generic list collection. Please note that I have used latest version of C# (3.0) that supports var keyword and other features I have used in below code snippets.
/// <summary>
/// Load records from the database using DataReader
/// </summary>
/// <returns></returns>
public List<Person> LoadThroughDataReader()
{
var list = new List<Person>();
using (SqlConnection conn = new SqlConnection(connStr))
{
using (SqlCommand cmd = new SqlCommand("LoadAll", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Person p = new Person()
{
Age = reader.GetInt32(reader.GetOrdinal("Age")),
FirstName =
reader.GetString(reader.GetOrdinal("FirstName")),
LastName =
reader.GetString(reader.GetOrdinal("LastName"))
};
list.Add(p);
}
}
conn.Close();
}
return list;
}
}
/// <summary>
/// load returns from database using DataTable
/// </summary>
/// <returns></returns>
public List<Person> LoadThroughDataTable()
{
var list = new List<Person>();
using (SqlConnection conn = new SqlConnection(connStr))
{
using (SqlCommand cmd = new SqlCommand("LoadAll", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter ad = new SqlDataAdapter(cmd))
{
DataTable table = new DataTable();
conn.Open(); // open the connection
ad.Fill(table);
conn.Close(); // close the connection
// loop through all rows
foreach (DataRow row in table.Rows)
{
Person p = new Person()
{
Age = int.Parse(row["Age"].ToString()),
FirstName = row["FirstName"].ToString(),
LastName = row["LastName"].ToString()
};
list.Add(p);
}
}
}
return list;
}
}
You may wonder why these two methods when both are doing the same thing. I prefer using DataReader when I have lesser amount of data from the database and loop through because DataReader expect live connection when it loops through all the records. For large amount of data, it may be a bottleneck for the database to keep the connection alive and loop through. So for large amount of data I prefer to fill the DataTable, close the database connection and then loop through all the records do the required operation.
Once you have your Data Access Layer method ready to return the generic list collection, you can call it through your business layer (My business layer class name isPersonBAL) as follows:
/// <summary>
/// load records through data reader
/// </summary>
/// <returns></returns>
public List<Person> LoadThroughDataReader()
{
return new PersonDAL().LoadThroughDataReader();
}
/// <summary>
/// load records through datatable
/// </summary>
/// <returns></returns>
public List<Person> LoadThroughDataTable()
{
return new PersonDAL().LoadThroughDataTable();
}
As I do not have any logic in the Business Layer, so I have simply instantiated the PersonDAL data access layer object and called the respective methods.
Subsequently, this business layer methods can be called from presentation layer as follows:
GridView g1 = new GridView();
g1.DataSource = new PersonBAL().LoadThroughDataReader();
g1.DataBind();
PlaceHolder1.Controls.Add(g1);
GridView g2 = new GridView();
g2.DataSource = new PersonBAL().LoadThroughDataTable();
g2.DataBind();
// I have a place holder control in the .aspx
page in which both above gridview is added
PlaceHolder1.Controls.Add(g2);
As GridView DataSource supports generic list also as data source
so we can directly assign the business layer method as the GridView datasource
and all the records from the generic list collection will be populated as rows
into the GridView. All the properties of the Person object will be treated as the column of the
GridView unless you have explictely assigned the columns in the GridView.
4-Tier
Architecture in ASP.NET with C#
http://www.dotnetfunda.com/articles/show/18/4-tier-architecture-in-aspnet-with-csharp
DataTable
vs. BindingList<T>
We were having a discusion today about the merits of using
DataTables vs. BindingList<T> (a generic in .NET 2.0) for loading up
domain objects into the UI layer (say to display on a grid). My gut feel is
telling me DataTables are evil and wrong, but I don't have a lot of hard
evidence to choose one over the other. We brainstormed some pros and cons for
each and they're listed below.
- DataTable
- Pros
- Simple to implement, not much
code needed
- Can use select statements to
retrieve values
- Change events are managed
within the object automagically
- Display handling for errors
built-in (when binding to grids)
- Cons
- Human errors (typos on column
names for example) can be exposed at runtime and can't be easily tested
- Need to implement DataViews
in order to sort or filter
- Can't test for type safety
(or as Scott says DataTables are bowls of fruit)
- Difficult to implement
business rules or logic
- Bloatware, lot of extra
baggage for features you don't need
- BindingList<T>
- Pros
- No mapping needed
- Strongly typed and type-safe
- Loosly coupled compared to a
data table -> mapping columns -> domain object
- More extensible via
superclasses, interfaces, etc.
- Cons
- Must iterate through list to
find items
- Must implement some mechanism
(like a decorator pattern) to respond to change events
- More short term investment to
learn and implement
Good Article to under stand alll above concept
http://imar.spaanjaars.com/416/building-layered-web-applications-with-microsoft-aspnet-20-part-1
No comments:
Post a Comment