Code Smith 6.5 在ERP開發中的應用


ERP開發中有大量的代碼是可以用代碼生成器來生成。選擇代碼生成器有二種思路

  • .NET代碼開發 優點是可集成到ERP開發工具中,定制化的開發,生成的代碼有爭對性
  • 使用第三方的工具,比如Code Smith或是T4,優點是借助於模板生成,靈活性高。缺點是要推廣技術的話,相應的代碼生成器也要熟悉,並且會有版權的問題。

ERP程序中,有四種類型的代碼,可借助於Code Smith來生成。

 

  1. Interface 數據訪問接口

  2. 接口與實現分離,可增加系統的靈活性。接口代碼的例子如下

using System.Collections.Generic;
using System.Data;
using System.Text;
using SD.LLBLGen.Pro.ORMSupportClasses;

using Foundation;
using Foundation.FactoryClasses;
using Foundation.EntityClasses;
using Foundation.HelperClasses;
using Foundation.InterfaceClasses;
using Foundation.DatabaseSpecific;

namespace Foundation.InterfaceClasses
{
    public interface ICompanyManager
    {
         CompanyEntity GetCompany(System.String Companycode);
         CompanyEntity GetCompany(System.String Companycode,IPrefetchPath2 prefetchPath);
         CompanyEntity GetCompany(System.String Companycode,IPrefetchPath2 prefetchPath,ExcludeIncludeFieldsList fieldList);
    
         EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket);
         EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket,ISortExpression sortExpression);
         EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket,ISortExpression sortExpression, IPrefetchPath2 prefetchPath);
         EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList);
    
         CompanyEntity  SaveCompany(CompanyEntity  company);
         CompanyEntity  SaveCompany(CompanyEntity  company ,EntityCollection entitiesToDelete);
         CompanyEntity  SaveCompany(CompanyEntity company, EntityCollection entitiesToDelete, string seriesCode);
    
         void DeleteCompany(CompanyEntity  company);
    
         bool IsCompanyExist(System.String Companycode);
         bool IsCompanyExist(IRelationPredicateBucket filterBucket);
         int  GetCompanyCount(IRelationPredicateBucket filterBucket);
        
         CompanyEntity CloneCompany(System.String Companycode);
         void PostCompany(System.String Companycode);
         void PostCompany(CompanyEntity company);    
    }
}
 

Code Smith基於模板生成代碼,把你需要實現的代碼做成模板,再替換需要改變的值,很輕松的就完成模板編程。

image

 

Implementation 數據訪問實現

針對接口,實現對應的接口方法。

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using SD.LLBLGen.Pro.ORMSupportClasses;
using Foundation;
using Foundation.FactoryClasses;
using Foundation.EntityClasses;
using Foundation.HelperClasses;
using Foundation.InterfaceClasses;
using Foundation.DatabaseSpecific;
using Foundation.Managers;
using Foundation.Common;

namespace Foundation.Managers
{
    public class CompanyManager :   Foundation.Common.ManagerBase, ICompanyManager
    {
        public CompanyEntity GetCompany(System.String Companycode)
        {
            return GetCompany(Companycode,null);
        }

        public CompanyEntity GetCompany(System.String Companycode,IPrefetchPath2 prefetchPath)
        {
            return GetCompany(Companycode,prefetchPath,null);
        }
          
        public CompanyEntity GetCompany(System.String Companycode,IPrefetchPath2 prefetchPath,ExcludeIncludeFieldsList fieldList)
        {
            CompanyEntity  _Company=new CompanyEntity(Companycode);
            using (DataAccessAdapterBase adapter=GetCompanyDataAccessAdapter())
            {
                bool found=adapter.FetchEntity(_Company, prefetchPath, null, fieldList);
                if (!found) throw new Foundation.Common.RecordNotFoundException("Invalid Company");
            }
            return _Company;
        }
        
        public EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket)
        {
            return   GetCompanyCollection(filterBucket,null);
        }
        
        public EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket,ISortExpression sortExpression)
        {
            return   GetCompanyCollection(filterBucket,sortExpression,null);
        }
        
        public EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket,ISortExpression sortExpression, IPrefetchPath2 prefetchPath)
        {
            return   GetCompanyCollection(filterBucket,sortExpression,prefetchPath,null);
        }
        
        public EntityCollection GetCompanyCollection(IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList)
        {
            EntityCollection CompanyCollection =new  EntityCollection(new  CompanyEntityFactory());
            using (DataAccessAdapterBase adapter =GetCompanyDataAccessAdapter())
            {
                adapter.FetchEntityCollection(CompanyCollection, filterBucket, 0,sortExpression, prefetchPath, fieldList);
            }
            return  CompanyCollection ;
        }
        
        
        public CompanyEntity  SaveCompany(CompanyEntity  Company)
        {
            return SaveCompany(Company,null);
        }
        
        public CompanyEntity  SaveCompany(CompanyEntity  Company ,EntityCollection entitiesToDelete)
        {
            return SaveCompany(Company,entitiesToDelete,string.Empty);
        }        
        
        public CompanyEntity  SaveCompany(CompanyEntity Company, EntityCollection entitiesToDelete, string seriesCode)
        {
            using (DataAccessAdapterBase adapter =GetCompanyDataAccessAdapter())
            {
                try
                {
                    adapter.StartTransaction(IsolationLevel.ReadCommitted, "SaveCompany");
                    adapter.SaveEntity(Company, true, false);
                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
            return Company;
        }
        
        public void DeleteCompany(CompanyEntity  Company)
        {
            using (DataAccessAdapterBase adapter =GetCompanyDataAccessAdapter())
            {
                if (!adapter.IsEntityExist<CompanyEntity>(Company))
                return;

            try
            {
                adapter.StartTransaction(IsolationLevel.ReadCommitted, "DeleteCompany");
                adapter.DeleteEntity(Company);
                adapter.Commit();
            }
            catch
            {
                adapter.Rollback();
                throw;
            }
            }
        }        
        
        public bool IsCompanyExist(System.String Companycode)
        {
            RelationPredicateBucket filterBucket = new RelationPredicateBucket();
            filterBucket.PredicateExpression.Add(CompanyFields.Companycode==Companycode);        
            return IsCompanyExist(filterBucket);
        }
        
        public bool IsCompanyExist(IRelationPredicateBucket filterBucket)
        {
            return (GetCompanyCount(filterBucket) > 0);
        }

        public int GetCompanyCount(IRelationPredicateBucket filterBucket)
        {
            using (DataAccessAdapterBase adapter =GetCompanyDataAccessAdapter())
            {
                return adapter.GetDbCount<CompanyEntity>(filterBucket);
            }
        }
        
        public CompanyEntity CloneCompany(System.String Companycode)  
        {
            CompanyEntity   source = this.GetCompany(Companycode);  
            CompanyEntity   _Company = (CompanyEntity)CloneEntity(source);
            return _Company;
        }

        public void PostCompany(System.String Companycode)  
        {
            return;
        }
        public void PostCompany(CompanyEntity Company)
        {
            return;
        }
    }
}

有幾個要注意的地方:

1 重載方法 滿足不同的接口的需求。我這里實現的接口,相當於通用的接口方法,可以滿足今后各種需求。

舉例說明,增加一個字段,接口和實現不需要作任何改變。如果是只讀取被增加的字段值,請傳入參數ExcludeIncludeFieldsList以作為需要讀取的值。

減少字段也不需要作任何的變更;如果刪除了表,刪除相應的Interface類型和Manager類型即可。

2  所有的CRUD的接口方法,均已經實現。

Create,Update => Save接口

Remove => Delete接口

 

UI 界面層代碼生成

private ICompanyManager _CompanyManager = null ;
private CompanyEntity  _Company = null ;


protected override void OnLoad(EventArgs e)
{
    if(!DesignMode)
        this._CompanyManager = ClientProxyFactory.CreateProxyInstance<ICompanyManager>();
    base.OnLoad(e);
}

protected override void InitNavigator(InitNavigatorArgs args)
{
    base.InitNavigator(args);
    args.SortExpression.Add(CompanyFields.Companycode | SortOperator.Ascending);
}

protected override EntityBase2 LoadData(Dictionary<string, string> refNo)
{
    base.LoadData(refNo);   
    string Companycode=string.Empty;
    if(refNo.TryGetValue("Companycode", out Companycode))
    {        
        IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.CompanyEntity);
        _Company = _CompanyManager.GetCompany(Companycode,prefetchPath);    
    }
    else
    {
        _Company = new CompanyEntity();
    }
   return _Company;
}

protected override void BindControls(EntityBase2 entity)
{
    base.BindControls(entity);
    this.currencyBindingSource.DataSource = entity;
}

protected override EntityBase2 Add( )
{
    base.Add();
    this._Company = new CompanyEntity();
    return _Company;
}

protected override EntityBase2 Save(EntityBase2 entityToSave, EntityCollectionNonGeneric entitiesToDelete, string SeriesCode)
{
    CompanyEntity _Company = (CompanyEntity)entityToSave;
    this._Company =this._CompanyManager.SaveCompany(_Company);
    return _Company;
}

protected override void Delete(EntityBase2 entityToDelete)
{
    base.Delete(entityToDelete);
    CompanyEntity  Company = (CompanyEntity)entityToDelete;
    this._CompanyManager.DeleteCompany(Company);
}

protected override object Clone(Dictionary<string, string> refNo)
{
    base.Clone(refNo);
    string ccy = string.Empty;
    refNo.TryGetValue("Ccy", out ccy);
    return null;
}

protected override void ReleaseResources( )
{
    base.ReleaseResources();
    try
    {
        _Company = null;
        _CompanyManager= null;
    }
    catch
    {

    }
}

界面層的增刪查改接口,數據綁定接口都已經生成。需要修改的地方,則是定制化代碼的區域。比如增加一個公司時,它的創建日期應該為當前系統時間,創建人應該是當前登陸系統的用戶。

 

Validation 驗證代碼

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using SD.LLBLGen.Pro.ORMSupportClasses;

using Foundation;
using Foundation.FactoryClasses;
using Foundation.EntityClasses;
using Foundation.HelperClasses;
using Foundation.InterfaceClasses;
using Foundation.DatabaseSpecific;

namespace Foundation.ValidatorClasses
{
    [Serializable]
    public partial class CompanyEntityValidator : ValidatorBase
    {
         public override void ValidateEntityBeforeSave(IEntityCore involvedEntity)
        {
            base.ValidateEntityBeforeSave(involvedEntity);
            CompanyEntity  company  = (CompanyEntity)involvedEntity;

            if (company.IsNew)
            {
                
            }
           
        }
        
        public override void ValidateEntityBeforeDelete(IEntityCore involvedEntity)
        {
            base.ValidateEntityBeforeDelete(involvedEntity);
            CompanyEntity company = (CompanyEntity)involvedEntity;          
             
        }
        
        public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
        {
            bool result = base.ValidateFieldValue(involvedEntity, fieldIndex, value);
            if (!result) return false;
            CompanyEntity  company = (CompanyEntity)involvedEntity;
            
            switch ((CompanyFieldIndex)fieldIndex)
            {
                case SalesmanFieldIndex.Rank:
                    return this.ValidateRank((decimal)value);
                case SalesmanFieldIndex.Supervisor:
                    return this.ValidateSupervisor((string)value, salesman);
            }

            return true;
        }
    }   
}

數據的驗證有二個方面,一個是實體層的驗證,通常說的數據表的驗證,常常是業務邏輯所需要。比如新增加一個公司時,輸入公司的區域編碼時,需要在系統的區域編碼中驗證一下,它的區域編碼是否存在,如果不存在,則不允許保存。另一種驗證是字段層的驗證,比如輸入公司聯系方式的郵件地址時,需要驗證郵件格式是否正確。

四種類型的接口,滿足日常開發中所需要的大部分需求,再配合代碼生成器,一天做十來個頁面不是難事情,效率高,且質量也好,不會出錯。

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM