zoukankan      html  css  js  c++  java
  • 信息化基础建设 改善代码生成

    数据库字段映射

    当看到一个实体的属性,是否可以马上判断出它对应的数据库字段?

    _languageTranslation.KeyText, 比如看到这个KeyText的属性

    通常的做法是,去查找实体与数据库字段绑定的代码,以检查这个属性关联的数据库字段,代码可能是这样

    public LanguageTranslationEntity ReaderBind(IDataReader dataReader)

    {

    LanguageTranslationEntity model=new LanguageTranslationEntity ();

    object ojb;

    model. KeyText =dataReader[“KEY_TEXT"].ToString();

    model.Description=dataReader["Description"].ToString();

    }

    看到KeyText属性对应的数据库字段是KEY_TEXT. 但是,你需要用F12,转到定义,来帮忙查看这个ReaderBind方法,如果加上了接口与实现,还需要额外的搜索才能确定字段来源。

    改进的一种办法,是利用C#的Xml注释与智能感知,如下图

    clip_image002

    在生成的实体文件中,加上Xml注释,当鼠标指向一个属性时,可得到如下的效果

    clip_image003

    从这个图片中可以看出KeyText映射到表LanguageTransaction的KeyText字段,非常清晰。

    适当的修改一下生成实体的代码生成器,给字段加上一段类似于下面的Xml注释,可增强代码的可读性。

    <remarks>Mapped on table field: "LanguageTranslation"."KeyText"<br/>

    这是我对代码生成器的第一个Enhancement。

    一组实体文件

    实体名是LanguageTranslationEntity,我们通常会生成一个对应的LanguageTranslationEntity.cs文件。

    如果要给LanguageTranslationEntity.cs做一下修改,可能加入一些方法,F5,代码运行正常。

    如果有一天需要给LanguageTranslationEntity实体对应的数据库表增加一个字段,比如修改进间RevisedDate,这时,需要重新打开代码生成器,再生成一次代码,糟糕,原来写的代码丢失了。因为我们的代码生成器,只是简单的把文件写入到磁盘上去,如果存在原文件,默认的办法是覆盖原来的文件。

    这个问题有2个办法解决,改进代码生成器,或是改进生成的文件。

    改进代码生成器,把我们写的代码,放到代码文件中指定的区域中,

    比如,给生成的文件加上一些标签,在生成代码的时候,如果原来的文件是存在的,需要先提取这些标签中的字符串值,即程序员加入的自定义代码,然后把这些值插入到新生成的代码文件中,比如下面的标签例子

    // CODE_REGION_START

    自定义的代码逻辑放在这里

    // CODE_REGION_END

    第二种办法是,利用partial特性,生成2个文件,一个LanguageTranslationEntity.cs,另一个LanguageTranslationEntity.Logic.cs, 第二个文件,只生成一次,以后不重新生成,里面的内容全部放我们的自定义逻辑代码。

    表名与属性命名

    表名是Language,生成的实体名是LanguageEntity,在表名后面加Entity.

    如果喜欢把表名写成tblLanguage, 生成实体为LanguageEntity时,需要去掉tbl前缀。

    如果把表名写成LANGUAGE,要生成LanguageEntity,则需要转化一下大小写。把首字母大写,其余的小写。

    如果表名是ProductionControl,要生成ProductionControlEntity, 也是直接加Entity

    如果表名是DeptGroup,默认生成的实体为DeptGroupEntity, 为了可读性,可能需要转化一下,把Dept转成Department,生成的实体名为DepartmentGroupEntity.

    如果表名是DeptGrp,生成的DeptGrpEntity可读性就越来越差了。

    这时,转化Dept为Department,Grp为Group是必须的。

    要改善复合单词的表名对应的实体名,需要建立一个缩写字典表,和一个前缀表,在生成表名对应的实体名时,做替换处理,以增强可读性。

    这里还有一个问题,如何判断出DeptGroup是2个单词,一个简写和一个单词,

    而DeptGrp是2个单词的缩写,如果缩写恰好又是一个正确英语单词呢?

    还没有找到正确的区分单词的办法,折衷的方法是表名写成Dept_Grp,主动用下划线分开表名中的单词,在生成实体名时,只需要简单的Regex.Split就可以了。

    字段的命名,以及生成的属性名称,也可参考表名的规则,是同样的原理。

    接口与实现

    表名是Language,生成实体LanguageEntity, 实体文件名也叫LanguageEntity.cs

    如果同时加上接口与实现,如何命名文件名? 有以下几种方案参考

    方案1 接口文件名 ILanguage.cs , 实现文件名LanguageImplementation.cs

    方案2 接口文件名 ILanguageDAL.cs , 实现文件名LanguageDAL.cs

    方案3 接口文件名 ILanguageService.cs , 实现文件名LanguageService.cs

    方案4 接口文件名 ILanguageManager.cs , 实现文件名LanguageManager.cs

    用CodeSmith写模板文件,要改换上面提到的几种写法,非常容易

    如果需要为生成的接口支持WCF技术, 生成接口时,要主动接口添加ServiceContract特性,给方法添加OperationContract特性。如下面的例子
    [ServiceContract]
    public interface IWCFExample
    {
        [OperationContract]
        IEntity2 GetCustomer(string customerID);
     
        [OperationContract]
        IEntityCollection2 GetCustomers();
    }

    如果生成的接口要支持Web Services, 如下面的例子所示,加上WebMethod标签。

    [WebService]
    public class CustomerService : System.Web.Services.WebService
    {
            [WebMethod]
            public IEntity2 GetCustomer(string customerID)
            {
                   ……….
            }
    }

    好了,这些独立的部分考虑到了,用CodeSmith做好各个模板,生成代码起来很轻松

    clip_image004

    但是,CodeSmith有个问题,就是一次只能生成一段代码,如果我需要为数据库Northwind中所有表(或是指定的表)生成接口和实现文件呢,dirty的办法可以多次的在CodeSmith的输入的表名,生成文件,一个表一个个的做代码生成,再加上同时生成Interface和Manager,10个表*2,工作量是20次,如果是100个表,工作量是100*2, 200次运动。

    CodeSmith中有一个功能,就是可以直接调用它的API来运行代码生成,传入模板文件和必要的参数,调用代码就可以生成代码,而不必要运行CodeSmith软件本身。

    顺着这个思路,我制作出如下的实用工具

    clip_image006

    这个工具的目的,就是克服CodeSmith一次不能批量工作的局限。如上图所示,打开一个服务器,选择数据库,左边自动列出它的表名,双击表名或是拖动表名到中间的Listbox中,这里面的表,是要进行代码生成的表,再看右边的选项区,Template列出了指定文件下的所有模板,也就是要进行代码生成的模板,Parameter区域列出选定模板的参数,我使用=号把值填写到后面,下面的TargetFolder是生成的文件放置的目录。

    点击OK,一下次为这些表GBCURR Catalog DataSets Event History ModelDrill ModelPerspective Notifications

    生成了所有的Template中列出的模板的文件。

    表数量是8个,模板数据是7个,点击OK后,生成了7*8,56个文件,效率高。

    事实上,在升级.Net Remoting为WCF时,我就是使用这个技巧,一下将所有的接口文件实现成WCF的标准接口。

    Text to String

    在做报表或是数据库操作时,通常需要在查询分析器中写好SQL,如下

    SELECT

    ItemID, Path, Name, ParentID, Type,

    Content,

    Intermediate, SnapshotDataID, LinkSourceID,

    FROM dbo.Catalog

    然后运用SQL拼接技术,写成下面的格式

    string sql=" SELECT ItemID, Path, Name, ParentID, Type,"+

    " Content, Intermediate, SnapshotDataID, LinkSourceID, "+

    " FROM dbo.Catalog";

    这个转换的步骤,容易出错,也枯燥。如果有大量的SQL要转化成C#,工作量会相当大。

    由于掌握了代码生成技术 ,来看一下这个小程序

    clip_image008

    把SQL拷贝到上面的窗格中,选择要生成的代码方法(C#或是VB),点Generate Code,

    下面的窗格就写好我们需要的代码。

    这个小技巧可以省很多拼凑SQL的时间,而你需要付出的,就是写一个不到10行的C#程序。

    不可否认,SQL拼凑,在制作复杂的报表中还是相当有用的,复杂的报表要从大量的表中取数,运算,然后生成新的数据集,传送到报表中。用SQL拼凑做数据访问层,显然不是明智的决定,我以为。

  • 相关阅读:
    1032. Sharing (25)
    1031. Hello World for U (20)
    1030. Travel Plan (30)
    1029. Median (25)
    1028. List Sorting (25)
    1026. Table Tennis (30)
    win10 tortoiseSVN文件夹及文件图标不显示解决方法
    qrcode.react和jquery.qrcode生成二维码
    js来获取所有屏幕适配的总结
    handsontable整理
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2077245.html
Copyright © 2011-2022 走看看