Click here to Skip to main content
Email Password   helpLost your password?

Setup

Introduction

Tier Generator is a powerful tool for generating business and data layers in C#. It is a code generation tool that helps users to rapidly generate and deploy business and data layers for their applications. The idea behind this is to provide a utility (tool) to the developer that has the capabilities of quickly generating consistent and tested source code that will help to get projects started sooner and finished faster.

Tier Generator connects to a Microsoft SQL Server database server and generates business and data layers in C#. It also generates Stored Procedures for DML operations.

Business layer

Tier Generator generates code in two layers (business and data). It generates some classes for the each table in the database in the business layer. E.g., our database contains the table Employee. Tier Generator will generate the following files:

The Employee (business object) class contains the declaration of all instance fields along with properties. It also overrides the AddValidationRules method to associate the validation rules to the properties of the business object. It also contains an enum of all the fields.

public class Employee: BusinessObjectBase
{
   #region InnerClass

   public enum EmployeeFields
   {
     EmployeeID, Name, Password, Email, TeamID,DepartmentID, IsAdmin    
   }
    
   #endregion

   #region Data Members

   int _employeeID;
   string _name;
   string _password;
   string _email;
   int _teamID;
   int _departmentID;
   bool _isAdmin;

   #endregion

   #region Properties

   public int  EmployeeID
   {
     get { return _employeeID; }
     set
     {
        if (_employeeID != value)
        {
           _employeeID = value;
           PropertyHasChanged("EmployeeID");
        }
     }
   }

   public string  Name
   {
     get { return _name; }
     set
     {
       if (_name != value)
       {
         _name = value;
         PropertyHasChanged("Name");
       }
     }
   }
    .
    .
    .
    
   #endregion

   #region Validation

   internal override void AddValidationRules()
   {
     ValidationRules.AddRules(new Validation.ValidateRuleNotNull("EmployeeID", 
                                                                 "EmployeeID"));
     ValidationRules.AddRules(new Validation.ValidateRuleNotNull("Name", 
                                                                 "Name"));
     ValidationRules.AddRules(new Validation.ValidateRuleStringMaxLength("Name", 
                                                                    "Name",50));
     ValidationRules.AddRules(new Validation.ValidateRuleStringMaxLength("Password", 
                                                                         "Password",50));
     ValidationRules.AddRules(new Validation.ValidateRuleStringMaxLength("Email", 
                                                                         "Email",100));
     ValidationRules.AddRules(new Validation.ValidateRuleNotNull("TeamID", 
                                                                 "TeamID"));
     ValidationRules.AddRules(new Validation.ValidateRuleNotNull("DepartmentID", 
                                                                 "DepartmentID"));
     ValidationRules.AddRules(new Validation.ValidateRuleNotNull("IsAdmin", 
                                                                 "IsAdmin"));
   }

   #endregion
}

The EmpolyeesKeys (business object keys) class contains the list of primary keys of the table.

public class EmployeeKeys
{
    #region Data Members

    int _employeeID;

    #endregion

    #region Constructor

    public EmployeeKeys(int employeeID)
    {
      _employeeID = employeeID; 
    }

    #endregion

    #region Properties

    public int  EmployeeID
    {
      get { return _employeeID; }
    }

    #endregion

}

The EmployeeFactory (business factory) class contains the methods for the Insert, Delete, Update, and Select operations. It provides the following methods for the DML operations:

The factory class performs the DML operations with the help of the data layer.

public class EmployeeFactory
{
    #region data Members

    EmployeeSql _dataObject = null;

    #endregion

    #region Constructor

    public EmployeeFactory()
    {
      _dataObject = new EmployeeSql();
    }

    #endregion

    #region Public Methods

    public bool Insert(Employee businessObject)
    {
       if (!businessObject.IsValid)
       {
          throw new InvalidBusinessObjectException(
                           businessObject.BrokenRulesList.ToString());
       }

        return _dataObject.Insert(businessObject);

    }

    
    public bool Update(Employee businessObject)
    {
      if (!businessObject.IsValid)
      {
        throw new InvalidBusinessObjectException(
                         businessObject.BrokenRulesList.ToString());
      }
      
      return _dataObject.Update(businessObject);
    }

    public Employee GetByPrimaryKey(EmployeeKeys keys)
    {
       return _dataObject.SelectByPrimaryKey(keys); 
    }

     
    public List<Employee> GetAll()
    {
       return _dataObject.SelectAll(); 
    }

    public List<Employee> GetAllBy(Employee.EmployeeFields fieldName, 
                                         object value)
    {
      return _dataObject.SelectByField(fieldName.ToString(), value);  
    }

    public bool Delete(EmployeeKeys keys)
    {
       return _dataObject.Delete(keys); 
    }

    public bool Delete(Employee.EmployeeFields fieldName, object value)
    {
       return _dataObject.DeleteByField(fieldName.ToString(), value); 
    }

    #endregion

}

Data Layer

The data access file generated by the Tier Generator contains the methods for DML operations. It uses Stored Procedures for DML operations. The factory class methods call the data layer methods for insertion and deletion.

class EmployeeSql : DataLayerBase 
{
  
   #region Public Methods

   /// <summary>
   /// insert new row in the table
   /// </summary>
   /// <param name="businessObject">business object</param>
   /// <returns>true of successfully insert</returns>
   public bool Insert(Employee businessObject)
   {
     SqlCommand    sqlCommand = new SqlCommand();
       sqlCommand.CommandText = "dbo.[sp_Employee_Insert]";
       sqlCommand.CommandType = CommandType.StoredProcedure;

     // Use base class' connection object
     sqlCommand.Connection = MainConnection;

     try
     {                
       sqlCommand.Parameters.Add(new SqlParameter("@EmployeeID", SqlDbType.Int, 4, 
                                                  ParameterDirection.Output, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.EmployeeID));
       sqlCommand.Parameters.Add(new SqlParameter("@Name", SqlDbType.NVarChar, 
                                                  50, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.Name));
       sqlCommand.Parameters.Add(new SqlParameter("@password", SqlDbType.NVarChar, 
                                                  50, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.Password));
       sqlCommand.Parameters.Add(new SqlParameter("@Email", SqlDbType.NVarChar, 
                                                  100, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.Email));
       sqlCommand.Parameters.Add(new SqlParameter("@TeamID", SqlDbType.Int, 
                                                  4, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.TeamID));
       sqlCommand.Parameters.Add(new SqlParameter("@DepartmentID", SqlDbType.Int, 
                                                  4, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.DepartmentID));
       sqlCommand.Parameters.Add(new SqlParameter("@IsAdmin", SqlDbType.Bit, 
                                                  1, ParameterDirection.Input, 
                                                  false, 0, 0, "", 
                                                  DataRowVersion.Proposed, 
                                                  businessObject.IsAdmin));
       MainConnection.Open();
       
       sqlCommand.ExecuteNonQuery();
       businessObject.EmployeeID = 
         (int)sqlCommand.Parameters["@EmployeeID"].Value;

       return true;
     }
     catch(Exception ex)
     {
       throw new Exception("Employee::Insert::Error occured.", ex);
     }
     finally
     {
       MainConnection.Close();
       sqlCommand.Dispose();
     }
  }

  #endregion
}

How to use

The code generated by the Tier Generator is easy to use. Open the generated project in Visual Studio 2005 and compile it. Run the Stored Procedures script in the the database which is generated by the Tier Generator. You can find the SQL script file in the generated folder.

Add a new Windows/web project in the existing project and add the DLL of the generated code to it. Add app.config for Windows applications and web.config for web applications. Get the connection string from the generated app.config file. You will get this file in the generated folder.

  <appSettings>
     <add key="Main.ConnectionString" 
             value="Data Source=localhost;Initial Catalog=School;
                    User Id=sa;Password=sa" />
  </appSettings>

Here is the code sample for inserting a new record:

public void AddNewRecord()
{
    Employee emp = new Employee();
    emp.EmployeeID = 1;
    emp.FirstName = "Shakeel";
    emp.LastName = "Iqbal";
    .
    .
    .
    .
    
    EmployeeFactory empFact = new EmployeeFactory();
    empFact.Insert(emp);
}

The code sample for selecting all the records:

public void SelectAll()
{
     EmployeeFactory empFact = new EmployeeFactory();
     List<Employee> list = empFact.GetAll();   
    
    dataGrid1.DataSource = list;
}

Future enhancements

I have some future enhancements planned for the Tier Generator, and I have plans to launch the next version of the Tier generator. In this version, I will improve my business and data layers, and I will also provide the following features:

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralTierGenerator
nishantha bandara
19:37 2 Mar '10  
Hi Sakeel,

I have been using your code generation tool for some time and find it very useful for rapid application development. I did convert (did some minor changes ) and use it now even with mysql. What about your second version you planned.

I would like to join with you and enhance this with advance features such as transaction support.

Please mail me at nsbandara@gmail.com we can discuss.

Thanks,
Nishantha
GeneralAbandoned?
ipadilla
1:29 2 Jan '10  
Definitily this project is abandoned?, what´s a paty...
ipadilla
GeneralRe: Abandoned?
Shakeel Iqbal
6:48 2 Jan '10  
Dear friend, it was my plan that i would write the second version of Tier Generator, but unfortunately i could not complete it in time. Although i had started work on it 6 month ago and i completed almost 30 percent of my second version. but i stopped it because of my some other commitments.

Sorry for delay dear Frown

Shakeel Iqbal

GeneralRe: Abandoned?
ipadilla
2:10 3 Jan '10  
Hi Shakeel Iqbal,
thank you very much for answering, I hope you can find time in the future.
ipadilla
GeneralHave you abandoned this project
VenerableBede
4:38 16 Dec '09  
Have you abandoned this project Shakeel?
GeneralRe: Have you abandoned this project
Shakeel Iqbal
6:50 2 Jan '10  
Dear friend, it was my plan that i would write the second version of Tier Generator, but unfortunately i could not complete it in time. Although i had started work on it 6 month ago and i completed almost 30 percent of my second version. but i stopped it because of my some other commitments.

Sorry for delay dear Frown

Shakeel Iqbal

GeneralRe: Have you abandoned this project
gravbox
17:37 8 Jan '10  
I have looked at this and it is impressive. Many of these concepts are also implemented in the nHydrate generator as well.

http://nhydrate.codeplex.com/[^]
GeneralAdapted for SQL Compact
Atlas2002
5:34 4 Dec '09  
First I would like to say excellent job on the framework and tier generator. You have my vote of 5.

I have made some modifications to your template code and Tier Generator to support Tier generation for a SQL Compact database. The only major change I had to make was seperating connection management and generation of SQL statements. Instead of entering the database information in the config file I moved the connection object so that the sdf file could be provided by the user and managed similar to a connection pool. This was a minor change. Instead of using stored procedures which SSCE does not support I had to use embedded SQL with the SQLCEParameter support.

The final change was to support simulated views with entity generation. The tier generator now takes a SQL statement and analyzes the resulting dataset to generate a read only entity collection similar to a regular table. Support for select by field and select by key are still supported and generated based on the underlying tables.
GeneralImpressive
VenerableBede
3:28 25 Nov '09  
Nice job. Thanks for sharing.

Any idea when your new version will come out?
GeneralPlease Include BugList too
Member 1591127
2:14 17 Aug '09  
Yep as i have already mentioned its best solution over internet cloud, so please include known bugs
in your article. Wink
Suggest to post it on codeplex and let the people join you to help and enhance.
Smile
GeneralGreat Solution but few bugs and enhancements required
Member 1591127
2:08 17 Aug '09  
Dear Shakeel,
I have to design i new lightwieght project, i was looking for a code generation solution which provides entity, collection and use of generics, from past few days i googled a lot to find out best one. i tried LLBGenPro, Codesmith and plenty other, though LLbGenpro and Codesmith are good enough but paid and providing few advance features like lazy loading, unit of work pattern(LLbGenpro only) to handle transactions, My application has to be any open source external lib independent as it belong to Banking app so cant use Nhibernate stuff too, finally came across your application which is "best suitable" Smile for light weigted application and for big one too, so thanks a lot, I found one bug,
You are using SqlDatabSchema.cs to populate tables and vies through PopulateTables function, heres a bug, if tables or views are badly named like having spaces "View view ViEw" then application crashes as you have used string(0) reader.GetString(0) instead of column names which fails in this case, so please fix.
I found your business layer cosist of both entity and data access layer which you have merged in same solution.In a real n Tier application these are seperate layers like BLL,ENTITY,DAL let me know how could to modify generated code to build these layers and this is expected as enhancements.
One more point in real application a select statement is never made from a single table so could you provide feature to include columns from more than one tables to generate entity. (other orm does these
through deep loading which is nothing just load all realted tables in one go but why to load unnecessary columns if heavy transactions are not required)

Five from me as you have included ValidationSupport too You van Include Nullable Types and attributes support from Evil entity validation library(Codeplex) .
GeneralSQL 2005
mtone
10:21 15 Jul '09  
I am getting an empty Where clause in the Stored procedures. I have primary keys but this is running against a SQL 2005 database, could that be an issue?

Is there something I can fix opposed to completeing the sql WHERE by hand on a bunch of tables.
GeneralRe: SQL 2005
Shakeel Iqbal
19:50 16 Jul '09  
It is known issue in Tier Generator that if any table does not has primary key then it generates empty WHERE clause.

But if your table has primary key then it should generate WHERE clause in store procedures. Please assign primary key to your each table and regenerate code.

There is no such issue in Tier Generator that if table has primary key and it generates empty WHERE clause in store procedure.

Shakeel Iqbal

Generalclosing Datareader
flyingbaobao
18:07 14 May '09  
Hi,Shakeel Iqbal
I don't need spend time saying how good your tool is. I'll give it 4.9.
I have a small question here. Let's look at some sample code,

SqlCommand sqlCommand = new SqlCommand();
sqlCommand.CommandText = "dbo.[Car_SelectByField]";
sqlCommand.CommandType = CommandType.StoredProcedure;

// Use connection object of base class
sqlCommand.Connection = MainConnection;

try
{

sqlCommand.Parameters.Add(new SqlParameter("@FieldName", fieldName));
sqlCommand.Parameters.Add(new SqlParameter("@Value", value));

MainConnection.Open();

IDataReader dataReader = sqlCommand.ExecuteReader();

return PopulateObjectsFromReader(dataReader);

}
catch (Exception ex)
{
throw new Exception("Car::SelectByField::Error occured.", ex);
}
finally
{

MainConnection.Close();
sqlCommand.Dispose();
}

Your code has done connection close and sqlcommand.dispose in finally block, which is very good. However shoudn't we also Close the IDataReader dataReader as well in the try block after loading the business object. Since you declare the IDataReader dataReader in the try block, there's no way to access it out of the try block. If we want to close the dataReader, we have to do it in the try block.
I welcome your opinion on this.
Cheers.
GeneralWell done!
Member 2749129
8:52 6 Apr '09  
Very good job!Thumbs Up
GeneralMulti Table
Dawit Kiros
21:02 1 Apr '09  
Hi Shakeel, Can u please give me an example to display values in a datagrid from different tables that have a many to many relationships?

Thanks in Advance.Thumbs Up
GeneralRe: Multi Table
Shakeel Iqbal
21:13 2 Apr '09  
Hi Dawit.

Tier generator generates business and Data Layer object for single table only. In this release it does not provide a facility to create business object using multiple tables.

There are 2 ways to achieve it

1). You can write store procedure, call this store procedure in data layer and then you can return data table from business object and bind this object with grid.
(but it is not good approach to achieve required result. because some methods will return strong type list and some will return data table. So your design will not be consistent.)

2). You can also create new classes in business and data layer for custom list. and add property in business object which you want to show on grid. Call store procedure which will return data from more then one table and assign return values to custom list.

I will start work on new version soon and i will provide these facility in Tier Generator.

Thanks.

Shakeel Iqbal

GeneralRe: Multi Table
Dawit Kiros
9:31 4 Apr '09  
Thanks Shakeel..................
Question[Message Deleted]
Dawit Kiros
9:46 17 Mar '09  

AnswerRe: Badley need the Enhancement..........
Shakeel Iqbal
9:59 17 Mar '09  
Hopefully, I will post new version after 2 months. i am going to start work on it soon.

Shakeel Iqbal

GeneralHow can I use Transactions with this tier?
Member 2109013
15:48 9 Mar '09  
Hi~~!! I like this article~~ ^^
but I wonder if I use Transactions with businesslayer,Datalayer.
Big Grin
GeneralRe: How can I use Transactions with this tier?
Shakeel Iqbal
6:49 10 Mar '09  
Actually It generate data in One to One mapping. For implementing Transaction you need to change too much code.

Thanks!

Shakeel Iqbal

GeneralRe: How can I use Transactions with this tier?
Member 2109013
19:32 10 Mar '09  
Thanx for your reply
If it is possible, I'd like to use your code.

emmm... I just did it like that.

ex>

public class Biz_F01_Tx
{
public bool InsertUser(TB_F01_EMPO empo,TB_F01_EMPOCMP empocmp)
{
TB_F01_EMPOFactory empoFac = new TB_F01_EMPOFactory();
TB_F01_EMPOCMPFactory empocmpFac = new TB_F01_EMPOCMPFactory();

using (TransactionScope scope = new TransactionScope()) // Transaction code
{
try
{
empoFac.Insert(empo); // insert method
empocmp.EmpID = empo.EmpID;//output empID

empocmpFac.Insert(empocmp); //another insert method
ExceptionLog.WriteLog("transaction Test", "ETC");//File Write Test

scope.Complete();
return true;
}
catch(Exception e) {
ExceptionLog.WriteLog("", "BIZ", e);
return false;
}
}
}
}


For a while testing...
I saw transaction being well..
However, I worried about datalayer code...like that

try{
.....
MainConnection.Open();
.....
}
finally
{
.....
MainConnection.Close();
.....
}

each Public Methods have connection handling(MainConnection.Open(),MainConnection.Close())

isn't it make a memory leaking?
GeneralExcellent work
ipadilla
22:38 21 Jan '09  
Please, we need a new release because this is the best generator we can find in the net.

I have found a bug when generating code from a table with blank spaces like "Orders details" from Northwind database.

Congratulations for this interesting work.
ipadilla
GeneralNice Work
ArpitDubey
7:12 14 Nov '08  
Good Job

Expect you may dev shortly. Complete Relations sproc sys also.

godd luck for it. plz keep it up

Arpit.


Last Updated 26 Jul 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010