ASP.NET 4.0 and the Entity Framework 4 - Part 4 - A 3 Layered Approach to the Entity Framework
page 4 of 10
by Vince Varallo
Feedback
Average Rating: 
Views (Total / Last 10 Days): 94367/ 159

Step 3: Create the Business Logic Layer

The Business Logic Layer (BLL) sits between the User Interface and the Data Access Layer and implements the business logic of the application.  This is where validation rules should be implemented. 

1.    Right click on the OrderSystem solution in the Solution Explorer and select Addà New Project… from the pop-up menu.

2.    Select Visual C# Class Library and name the project OrderSystemBLL and click the OK button.

3.    Right click on the References in the BLL project and select Add Reference.  The Add Reference dialog box should appear.

4.    Click on the Projects tab and select OrderSystemDAL from the list of projects.  Click the OK button.  You can now use the classes declared in the DAL project

5.    You also need to add a reference to the System.Data.Entity namespace.

6.    Right click on the Class1.cs file in the Solution Explorer and select Rename from the pop-up menu.  Rename the file UserAccountEO.  The EO is a suffix which stands for Edit Object.  This distinguishes this class from the UserAccount entity that was declared in the DAL.  Visual Studio will prompt you to rename all reference to this class, you should click the Yes button.

7.    Add the following using statements.

using System.Collections;
using OrderSystemDAL;

8.    Add the following property declarations to the class.

public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime InsertDate { get; set; }
public DateTime UpdateDate { get; set; }
 
public string FullName
{
    get
    {
        return LastName + ", " + FirstName;
    }
}

The FullName property is a read only property that is useful when displaying this object to the user.

9.    Add the follow methods to implement the logic for saving a record to the database.  The Save method will either add or update a record depending of the Id of the object.  A zero Id indicates that the record should be added.  The data in this object is validated before it tries to save it to the database.  If there are any validation errors the record will not be saved and the specific validation error message will be passed back to the caller.

public bool Save(ref ArrayList validationErrors)
{
    ValidateSave(ref validationErrors);
 
    if (validationErrors.Count == 0)
    {
        if (Id == 0)
        {
            Id = UserAccountsData.Insert(FirstName, LastName, DateTime.Now);
        }
        else
        {
            UserAccountsData.Update(Id, FirstName, LastName, DateTime.Now);
        }
        return true;
    }
    else
    {
        return false;
    }
}
 
private void ValidateSave(ref ArrayList validationErrors)
{
    if (FirstName.Trim() == "")
    {
        validationErrors.Add("The First Name is required.");
    }
 
    if (LastName.Trim() == "")
    {
        validationErrors.Add("The Last Name is required.");
    }
}

10. Now you can add the methods for deleting a record.  If you needed to do any referential integrity checks or other validation before deleting you would add the logic in the ValidateDelete method.

public void Delete(ref ArrayList validationErrors)
{
    ValidateDelete(ref validationErrors);
 
    if (validationErrors.Count == 0)
    {
        UserAccountsData.Delete(Id);
    }
}
 
private void ValidateDelete(ref ArrayList validationErrors)
{
    //Check for referential integrity.
}

11. The next methods to add will allow a caller of this object to load a specific record.

public bool Select(int id)
{
    UserAccount userAccount = UserAccountsData.SelectById(id);
 
    if (userAccount != null)
    {
        MapData(userAccount);
        return true;
    }
    else
    {
        return false;
    }
}
 
internal void MapData(UserAccount userAccount)
{
    Id = userAccount.Id;
    FirstName = userAccount.FirstName;
    LastName = userAccount.LastName;
    InsertDate = userAccount.AuditFields_InsertDate;
    UpdateDate = userAccount.AuditFields_UpdateDate;
}

12. The last method to add will create a list of UserAccountEO objects.  This is used when you want to select all the records from the UserAccounts table.

public static List<UserAccountEO> SelectAll()
{
    List<UserAccountEO> userAccounts =  new List<UserAccountEO>();
 
    List<UserAccount> userAccountDTOs = UserAccountsData.SelectAll();
 
    foreach (UserAccount userAccountDTO in userAccountDTOs)
    {
        UserAccountEO userAccountEO = new UserAccountEO();
        userAccountEO.MapData(userAccountDTO);
        userAccounts.Add(userAccountEO);
    }
 
    return userAccounts;
}

View Entire Article

User Comments

Title: Where is the UserAccounts table diagram?   
Name: Fernando Linhares
Date: 2012-07-11 6:12:05 PM
Comment:
Hello,
Thanks for the article series.
Where is the UserAccounts table diagram picture?
Thanks,
Fernando
Title: without stored procedures   
Name: Junior
Date: 2012-06-06 2:21:42 PM
Comment:
how would this approach without stored procedures ?
Title: problem   
Name: zia
Date: 2012-05-22 9:33:03 AM
Comment:
Brother i cant see the pictures u given in the project
Title: Mr   
Name: Varun Maggo
Date: 2011-03-16 4:16:28 AM
Comment:
You rockmaan!
Title: Nice work!   
Name: janmeis
Date: 2011-03-02 11:52:40 AM
Comment:
Thanks Vince, I've created the project according the article and it works fine! There's one minor bug, the SCOPEIDENTITY returned by the UserAccounts_Insert procedure is mapped as decimal not int, so in the item 16 the procedure must be as follows "...you need to change the "Returns a Collection Of" to Scalars and choose decimal from the list." Then it can be casted to int in the "public static int Insert". Link with the uploaded project is attached.
Title: connectionstring problem   
Name: Mark
Date: 2010-12-25 7:59:09 AM
Comment:
I am getting server error on data source keyword.

Keyword not supported: 'data source'.

Exception Details: System.ArgumentException: Keyword not supported: 'data source'.
Title: Lnking to a data Object   
Name: Richard
Date: 2010-10-01 4:12:41 PM
Comment:
So far so good, but now I have this BLL how do I use it say in a datagrid?
Title: Where is the concurrency management???   
Name: Matt
Date: 2010-07-30 12:52:28 PM
Comment:
Where is the concurrency management code? If you load a user account from the database and five minutes later the person clicks the submit button how do you handle the issue where someone else already updated that record and you need to check for that???
Title: Why add the DAL and BLL as separate projects?   
Name: Alan
Date: 2010-07-12 12:16:59 PM
Comment:
Even assuming that this is a good way to structure your application (which seems to be a matter of debate judging by other people's comments), why did you do the DAL and BLL as separate projects? I don't see any benefit at all to this.

Given that this is a web site, why not just add the .cs files for the DAL and BLL to the App_Code folder? You would then have the objects you need to separate the layers, but you wouldn't have the extra mess of separate projects and DLLs.
Title: Not convincing   
Name: Kum
Date: 2010-05-09 11:27:07 AM
Comment:
Duplicate data model, one generated by entity framework in DL and another hand written in BL...
There should be a better way.
Title: Is it realy the way?   
Name: Kristian
Date: 2010-05-07 6:54:23 AM
Comment:
Though I loved article part 1 and 2, this seems like a bad approach, like Mant wrote. Why do another mapping?
Title: Good Work   
Name: Rajbharat
Date: 2010-05-07 6:40:38 AM
Comment:
Its good and simple to follow..thanks for ur good work
Title: Appreciate that!   
Name: Waldek
Date: 2010-05-06 5:57:10 AM
Comment:
Thanks a lot Vince! Based on your articles all kinds of web.CRUD applications can now be built with a little hassle!
Title: use IsNullOrWhiteSpace instead if .Trim() == ""   
Name: Binoj Antony
Date: 2010-05-06 5:14:00 AM
Comment:
Suggest that you improvise FirstName.Trim() == "" with
string.IsNullOrWhiteSpace(FirstName).

Also the most of the else blocks that does just a return false , here you could eliminate the else and just write return false; (This last one is just an opinion)
Title: Bad Approach   
Name: Mant
Date: 2010-05-05 11:05:10 AM
Comment:
It seems what you have done is take the approach used in 1.1/2.0 with datasets then just swapped them with the Entity Framework completely missing the point of an ORM. I would suggest reading up on the Repository pattern, Unit of Work pattern, specification pattern and persistence ignorance. There are some great examples of using the framework out there, but just about everything in this one is a poor way of doing things.
Title: Great article!   
Name: Rich D.
Date: 2010-05-05 9:13:07 AM
Comment:
I loved the article. I was looking for some direction and ideas on how to create a BL. But, I thought the idea was to save much of the template hand coding by using t4 templates to generate POCO classes for the BL. The template for self-tracking entities looks promising for n-tier architectures.
Title: ASP.NET 4.0 and the Entity Framework 4 - Part 4 - A 3 Layered Approach to the Entity Framework   
Name: Ray
Date: 2010-05-05 3:16:16 AM
Comment:
Thanks Vince for a very helpful article.......
Title: ASP.NET 4.0 and the Entity Framework 4 - Part 4 - A 3 Layered Approach to the Entity Framework   
Name: tvs
Date: 2010-05-04 9:35:39 PM
Comment:
a very good article... well done vince...

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2019 ASPAlliance.com  |  Page Processed at 2019-07-19 4:53:53 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search