Sitemap

      Develop high speed .NET applications

Home

 
Products  |  Services  |  Partners  |  Press Room  |  Support  |  Buy  |  Download  |  Company
 
Alachisoft.com
a
  Articles
a
  Rapidly Develop GUI...
  Object Query Language...
  Sync Cache with SQL 2005
  Many-to-Many Relation...
  Inheritance in O/R Mapping
  Domain Objects Caching...
  Domain Object Persistence
  Five Reasons of O/R MAP...
  10 Features in O/R Map...
  Five Steps to RAD
       
   
   
       
C# Code Generation Overview
TierDeveloper generates .NET components in three layers. These are:
  • Business Layer: Contains two .NET components for each data object defined in a TierDeveloper project. They are:
    • Domain Object: This .NET component contains only the data members with "get" and "set" methods
    • .
    • Business Interface: This is a "stateless" component; meaning that it does not have any state information (data members) in it.
    • Collection Object: This .Net component is used to return a collection of Domain Objects from a query, or passing same to an operation.
       
  • Data Layer: Contains implementation of data persistence (in factory classes) and definition of hooks. 
    • Standard Methods: These are "Load", "Insert", "Delete", and "Update".
    • Operations: These have custom names and are customized versions of "Insert", "Load", or "Update" methods. The difference here is that these methods may not access all the attributes of the data object. The reason for these methods is to allow custom "Load" or "Update" functions for performance optimization purposes.
    • Query Methods: These usually return a Collection Object for the corresponding component.
    • Related Query Methods: These end up calling a Query method in a related data object and return a collection of DomainObject2 components where DomainObject2 is the related data object.
    • Stored Procedures: These methods make stored procedure calls and return output parameters of the stored procedure and/or a collection of objects if the stored procedure returns a rowset.
    • Bulk Operation Methods: These are either "Bulk Update" or "Bulk Delete" methods defined in the TierDeveloper project. These methods do not return any data.
    • Custom Hooks: If the user has specified that certain methods in a data object should call custom hooks that the user will implement, the corresponding code for it is also generated. Hooks allow you to modify the behavior of data objects without changing the actual data object code.
       
  • Integration Layer: The Integration layer works as a Service Provider to the client. It contains a Service Provider class, which contains static methods to instantiate the factory interface objects.

Domain Object Component

In our example, the namespace is "Northwind" and the Domain Object is "Customers". Below is the code:
public class Customers :PersistentObject, IComparable
{
    private
OrdersCollection _Orders = null;
    public
Customers()
    {
        SetupFields();
    }
    ///
<summary>
    /// Gets or sets the <c>CustomerID</c>
attribute value.
    ///
</summary>
    /// <value>The <c>CustomerID</c> attribute value.
</value>
    public String CustomerID
    {
       
get
        {
            if (!this["CustomerID"].Null)
                return (String) this["CustomerID"].Value;
           
else
                return null;
        }
       
set
        {
            this["CustomerID"].Value = value;
        }
    }
    ///
<summary>
    /// Gets or sets the <c>CompanyName</c>
attribute value.
    ///
</summary>
    /// <value>The <c>CompanyName</c> attribute value.
</value>
    public String CompanyName
    {
       
get
        {
            if (!this["CompanyName"].Null)
                return (String) this["CompanyName"].Value;
           
else
                return
null;
        }
   
    set
        {
            this["CompanyName"].Value = value;
        }
    }
    ///
<summary>
    /// Gets or sets the <c>ContactName</c>
attribute value.
    ///
</summary>
    /// <value>The <c>ContactName</c> attribute value.
</value>
    public String ContactName
    {
       
get
        {
            if (!this["ContactName"].Null)
                return (String) this["ContactName"].Value;

            else

                return null;
        }
       
set
        {
            this["ContactName"].Value = value;
        }
    }
    ///
<summary>
    ///
Gets or sets the <c>ContactTitle</c>
attribute value.
    ///
</summary>
    ///
<value>The <c>ContactTitle</c> attribute value.
</value>
    public
String ContactTitle
    {

        get

        {
            if (!this["ContactTitle"].Null)
                return
(String) this["ContactTitle"].Value;

            else

                return null;
        }
       
set
        {
            this["ContactTitle"].Value = value;
        }
    }
    ///
<summary>
    /// Gets or sets the <c>Address</c>
attribute value.
    ///
</summary>
    /// <value>The <c>Address</c> attribute value.
</value>
    public
String Address
    {
   
    get
        {
            if (!this["Address"].Null)
                return (String) this["Address"].Value;

            else

                return
null;
        }
       
set
        {
            this["Address"].Value = value;
        }
    }
    ///
<summary>
    ///
Gets or sets the collection of <c>Orders</c>
objects.
    ///
</summary>
    /// <value>The <c>OrdersCollection</c> object.
</value>
    public OrdersCollection Orders
    {
       
get
        {
            if(_Orders != null)
            {
                return _Orders;
            }

            else

                               
{
                _Orders = new OrdersCollection();
                return
_Orders;

                               
}
        }

        set

        {
            _Orders = value;

                    
}
    }
    public
  void SetNull(string szFieldName , bool bNull)
    {
        this[szFieldName].Null = bNull;
    }
    public  bool IsNull(string szFieldName)
    {
        return this[szFieldName].Null;
    }
    public
  int CompareTo(object obj)
    {
        if(obj is Customers)
        {
            Customers cmpCustomers = (Customers)obj;
            int
compareToValue = 0;
            if (this["CustomerID"].Null) return -1;
            compareToValue = CustomerID.CompareTo(cmpCustomers.CustomerID);
            if (compareToValue != 0)
                return compareToValue;
            return 0;
        }
        throw new ArgumentException("object is not a Customers");
    }
    public
override string ToString()
    {
        return "[Customers: " +
               " CustomerID = "
+ CustomerID +
               " CompanyName = " + CompanyName +
               " ContactName = " + ContactName +
               " ContactTitle = " + ContactTitle +
               " Address = " + Address + "]";

          
}
    private
void SetupFields()
    {
        AddField(new PersistentField("CustomerID", true, false,
                  TDevFramework.EDataType.eVarWChar, null));
        AddField(new PersistentField("CompanyName", true, false,
                  TDevFramework.EDataType.eVarWChar, null));
        AddField(new PersistentField("ContactName", false, false,
                  TDevFramework.EDataType.eVarWChar, null));
        AddField(new PersistentField("ContactTitle", false, false,
                  TDevFramework.EDataType.eVarWChar, null));
        AddField(new PersistentField("Address", false, false,
                  TDevFramework.EDataType.eVarWChar, null));
    }
}

Data Persistance Interface Definition

The interface definition below defines all the methods that the user has specified for this data object in TierDeveloper. The implementation of some of these methods is shown on this page.
public interface ICustomersFactory
{

    void
Load(Customers objInfo, int nDepth);
    void
Insert(Customers objInfo, int nDepth);
   
void Update(Customers objInfo, int nDepth);
   
void Delete(Customers objInfo, int nDepth);
   
void Save(CustomersCollection objList, int nDepth);
    void
DeleteColl(CustomersCollection objList, int nDepth);
    CustomersCollection
AllCustomers();
    Int32
AllCustomersCount();
    CustomersCollection
AllCustomersPR(Int32 nSP, Int32 nRecords);
    DataSet
AllCustomersDS();
    CustomersCollection
CustomersByCity(String strprmCity);
    DataSet
CustomersByCityDS(String strprmCity);
    CustomersCollection
CustomersByCriteria(String where, String orderBy);
    int
UpdatePostalCodeByCity(String strPostalCode, String strprmCity);
    int
DeleteCustomersByTitle(String strprmContactTitle);
    void
InsertShortProfile(Customers objInfo);
    void
UpdateAddress(Customers objInfo);
    void
LoadShortProfile(Customers objInfo);
    void
CustOrderHist(String strCustomerID, ref ArrayList returnValue);
    void
LoadChildren(Customers objInfo, int nDepth);
    void
DeleteChildren(Customers objInfo, int nDepth);
    void
LoadOrders(Customers objInfo, int nDepth);
    void
DeleteOrders(Customers objInfo, int nDepth);
}

Standard Load Method for Customers

The Load method loads a single-row from the Customers table and returns a Customers object containing data from it.
/// <summary>
///
  Load (Standard Load Method)
///
</summary>
///
<remarks>
///
  Loads a record from the <c>Customers</c> table given by
///
  the specified primary key.
///
</remarks>
///
<param name="objInfo">The <c>Customers</c> info object containing the primary key.</param>
///
<param name="nDepth">Specify the depth of children should be loaded.</param>
public
void Load(Customers objInfo, int nDepth)
{

    try

    
{
    
    bool bRecordsFound = false;
        
CheckPrimaryKeyValues(objInfo);
        
Prepare(STD_LOAD_SQL, USE_STORE_PROC);
        
BeginTransaction();
        
int status = 0;                    
        
ICustomersHooks hooks = new CustomersHooks();
        
status = hooks.PreLoad((TDevFramework.Connection)getConnection(), objInfo);
        
if (status != CustomersHooks.SUCCESS_CONTINUE)
        
{
           
SetStatus(status == CustomersHooks.FAIL_NONCONTINUE ?
                       EStatus.eFail : EStatus.eSuccess);

            
ReleaseCommand();
            
return;
        }

        
AddCmdParameter("@CustomerID", TDevFramework.EDataType.eVarWChar, objInfo.CustomerID,
                        TDevFramework.EParamDirection.eInput,objInfo.IsNull("CustomerID"));
        ExecuteReader();

        
while (Read())
        
{
           
FillPersistentObject(objInfo);
            
objInfo.IsNew = false;
            
objInfo.Dirty = false;
            
bRecordsFound = true;
        }

        
status = hooks.PostLoad((TDevFramework.Connection)getConnection(), objInfo);
        
if (status != CustomersHooks.SUCCESS_CONTINUE)
        
{
           
SetStatus(status == CustomersHooks.FAIL_NONCONTINUE ?
                       EStatus
.eFail : EStatus.eSuccess);

            
ReleaseCommand();
            
return;
        }
        ReleaseReader();

       
if(!bRecordsFound)
        
{
           
throw new RecordNotFoundException("No record found against given search criteria.");
        }

        
if (nDepth != 0)
        
{
           
LoadChildren(objInfo, nDepth - 1);
        }

        
SetStatus(EStatus.eSuccess);
        
ReleaseCommand();
    }

    
catch (RecordNotFoundException e)
    
{
       
SetStatus(EStatus.eSuccess);
        
ReleaseCommand();
        
throw e;
    }

    
catch (Exception e)
    
{
       
SetStatus(EStatus.eFail);
        
ReleaseCommand();
        
throw e;
    }

}

Query Method for Customers

This Query Method loads multiple rows from the Customers table and returns a collection of Customers objects with each object containing data from one row.

/// <summary>
///   AllCustomers (Query Method)
/// </summary>
/// <remarks>
/// </remarks>
/// <returns><c>CustomersCollection</c> object containing all the records
///   returned in the resultset.</returns>     
public CustomersCollection AllCustomers()
{
    Customers objInfo;
    CustomersCollection objList = new CustomersCollection();
    try
    {    
        Prepare(AllCustomers_SQL, USE_STORE_PROC);
        BeginTransaction();
        ExecuteReader();
        while (Read())
        {
            objInfo = new Customers();
            if (!IsNull("CustomerID"))
                objInfo.CustomerID = Convert.ToString(getValue("CustomerID"));
            if (!IsNull("CompanyName"))
                objInfo.CompanyName = Convert.ToString(getValue("CompanyName"));
            if (!IsNull("ContactName"))
                objInfo.ContactName = Convert.ToString(getValue("ContactName"));
            if (!IsNull("ContactTitle"))
                objInfo.ContactTitle = Convert.ToString(getValue("ContactTitle"));
            if (!IsNull("Address"))
                objInfo.Address = Convert.ToString(getValue("Address"));
            objInfo.IsNew = false;
            objInfo.Dirty = false;
            objList.Add(objInfo);
        }
        ReleaseReader();
        SetStatus(EStatus.eSuccess);
        ReleaseCommand();
    }
    catch (Exception e)
    {
        SetStatus(EStatus.eFail);
        ReleaseCommand();
        throw e;
    }
    return objList;
}

Bulk Update Method for Customers

Following is the code generated for "UpdatePostalCodeByCity", a bulk method that update the postal code of particular city.

/// <summary>
///   UpdatePostalCodeByCity (Bulk Update Method)
/// </summary>
/// <remarks>
///   <para>Updates all the record in <c>Customers</c> table matching the given criteria.</para>
///   <para>
///   </para>
/// </remarks>
/// <returns>The number of rows affected.</returns>  
public int UpdatePostalCodeByCity (String strPostalCode , String strprmCity)
{
    int result = 0;
    try
    {
        Prepare(UpdatePostalCodeByCity_SQL, USE_STORE_PROC);
        BeginTransaction();
        AddCmdParameter("@PostalCode", TDevFramework.EDataType.eVarWChar, strPostalCode,
                         EParamDirection
.eInput);
        AddCmdParameter("@prmCity", TDevFramework.EDataType.eVarChar, strprmCity,
                         EParamDirection
.eInput);
        result = ExecuteNonQuery();
        SetStatus(EStatus.eSuccess);
        ReleaseCommand();
    }
    catch (Exception e)
    {
        SetStatus(EStatus.eFail);
        ReleaseCommand();
        throw e;
    }
    return result;
}

Related Query Method for Customers

The Related Query Method actually returns a collection of related "Orders" object. It does this by calling a query method in the related data object.

/// <summary>
///   OrdersQuery (Query Method)
/// </summary>
/// <remarks>           ///  
///   </remarks>
/// <returns><c>OrdersCollection</c> object containing all the records
///   returned in the resultset.</returns>     
public OrdersCollection OrdersQuery( String strprmCustomerID)
{
    Orders objInfo;
    OrdersCollection objList = new OrdersCollection();
    try
    {    
        Prepare(OrdersQuery_SQL, USE_STORE_PROC);
        BeginTransaction();
        AddCmdParameter("@prmCustomerID", TDevFramework.EDataType.eVarChar, strprmCustomerID,
                         EParamDirection
.eInput);
        ExecuteReader();
        while (Read())
        {
            objInfo = new Orders();
            if (!IsNull("OrderID"))
                objInfo.OrderID = Convert.ToInt32(getValue("OrderID"));
            if (!IsNull("CustomerID"))
                objInfo.CustomerID = Convert.ToString(getValue("CustomerID"));
            if (!IsNull("EmployeeID"))
                objInfo.EmployeeID = Convert.ToInt32(getValue("EmployeeID"));
            if (!IsNull("OrderDate"))
                objInfo.OrderDate = Convert.ToDateTime(getValue("OrderDate"));
            if (!IsNull("RequiredDate"))
                objInfo.RequiredDate = Convert.ToDateTime(getValue("RequiredDate"));
            objInfo.IsNew = false;
            objInfo.Dirty = false;
            objList.Add(objInfo);
        }
        ReleaseReader();
        SetStatus(EStatus.eSuccess);
        ReleaseCommand();
    }
    catch (Exception e)
    {
        SetStatus(EStatus.eFail);
        ReleaseCommand();
        throw e;
    }
    return objList;
}

Stored Procedure Method for Customers

The Stored Procedure Method calls a stored procedure in the database. It passes any IN, IN/OUT, and OUT parameters to this stored procedure. If the stored procedure is returning a rowset then this method returns a collection containing the data.

/// <summary>
///
  CustOrderHist (Stored Procedure Method)
/// </summary>
///
<remarks>
///
  <para>Executes the stored procedure <c>CustOrderHist;1</c>.</para>

///
 
<para>

///
 
</para>

///
</remarks>
public void CustOrderHist(String strCustomerID , ref ArrayList returnValue)
{
     string sqlCmd = "CustOrderHist;1";
 
    ArrayList objList = new ArrayList();
     try
     {
         Prepare(sqlCmd, true);
         AddCmdParameter("@CustomerID", TDevFramework.EDataType.eVarWChar, strCustomerID,
                        TDevFramework.EParamDirection.eInput);
         ExecuteReader();
         while (Read())
         {
             ArrayList objInfo = new ArrayList();
            
int fieldCount = getFieldCount();
            
if(objList.Count == 0)
            
{
               
for (int index = 0; index < fieldCount; index++)
                
{
                   
objInfo.Add(getFieldName(index));
                }

                
objList.Add(objInfo);
                
objInfo = new ArrayList();
            }

            
for (int index = 0; index < fieldCount; index++)
            
{
               
objInfo.Add(getValue(index));
            }

            
objList.Add(objInfo);
        }

        
returnValue = objList;
        
returnValue = objList;
        
SetStatus(EStatus.eSuccess);
        
ReleaseCommand();
    }

    
catch(Exception ex)
    
{
       
SetStatus(EStatus.eFail);
        ReleaseCommand();

        
throw ex;
    }

}

Custom Hooks Inside Generated Code

TierDeveloper optionally generates "ObjectName" Hooks classes if the user has selected/specified "Pre" and "Post" hooks for certain methods of data object through data object settings in TierDeveloper. For example in this case TierDeveloper generates CustomersHooks.cs file. The "Pre" and "Post" Hook Methods for "InsertShortProfile" custom operation are shown below:

public int PreInsertShortProfile( TDevFramework.Connection Conn, Customers objInfo)
{

    return
SUCCESS_CONTINUE;
}

public
int PostInsertShortProfile( TDevFramework.Connection Conn, Customers objInfo)
{

    return
SUCCESS_CONTINUE;

}

Custom Operation Method with Hooks Being Called

This is the generated code for a Custom Insert Operation "InsertShortProfile". The "Pre" and "Post" hook methods (optional) are called before and after the database operation is performed.

/// <summary>
///
  InsertShortProfile (Custom Insert Method)
///
</summary>
///
<remarks>
///
  <para>Inserts partial record into <c>Customers</c> table.</para>
///
  <para>
///
  </para>
///
</remarks>
///
<param name="objInfo">The <c>Customers</c> info object to be inserted.</param>
public
void InsertShortProfile(Customers objInfo)
{

    try