• 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;
            }
        }   
    }

    数据的验证有二个方面,一个是实体层的验证,通常说的数据表的验证,常常是业务逻辑所需要。比如新增加一个公司时,输入公司的区域编码时,需要在系统的区域编码中验证一下,它的区域编码是否存在,如果不存在,则不允许保存。另一种验证是字段层的验证,比如输入公司联系方式的邮件地址时,需要验证邮件格式是否正确。

    四种类型的接口,满足日常开发中所需要的大部分需求,再配合代码生成器,一天做十来个页面不是难事情,效率高,且质量也好,不会出错。

     
     
  • 相关阅读:
    haproxy frontend 和backend
    haproxy 页面重定向(域名跳转)
    LWP::Simple 模块
    Perl LWP模块
    错误代码: 1582 Incorrect parameter count in the call to native function 'str_to_date'
    perl 面向对象 -> 符号使用
    跨域访问设置
    mysql 主从复制用户权限限制
    错误代码: 1045 Access denied for user 'skyusers'@'%' (using password: YES)
    sync_relay_log
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/3081203.html
Copyright © 2020-2023  润新知