The Last Day Of Summer

.NET技术 C# ASP.net ActiveReport SICP 代码生成 报表应用 RDLC
posts - 305, comments - 1973, trackbacks - 78, articles - 3
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

使用PowerDesigner进行代码生成

Posted on 2006-06-01 20:05 Cure 阅读(5726) 评论(13)  编辑 收藏 网摘 所属分类: 代码生成

    很多代码生成器都选择了从表结构来生成领域模型,这样的方案有一个前提,就是领域模型和数据库表结构是同构的,也就是说领域模型中的类和数据库中的记录结构十分吻合,这样数据库表结构可以简单的直接映射到领域模型。

 

    但是在业务逻辑比较复杂的情况下,对象方案和关系方案往往是不相配的,通常在两者之间有一个数据映射器来隔离两者,这时两者是相互不可见的,相互独立演变的。这样,基于表结构的代码生成领域模型的类就行不通了,而应该使用对象模型。而这样的代码生成几乎不需要自己在写代码生成器,可以使用PowerDesigner9

 

     PowerDesigner9自己就已经具有代码生成功能,你只要建立一个Object_Oriented Model(语言选择C#,类图),完成类设计后,使用Language菜单下的“Generate C# Code”。生成完后看看代码文件,所有的属性都没有getset方法,要想生成这两个方法,就要自己动手修改PowerDesigner的代码生成模板,可以选择Language菜单下的“Edit Current Object Language”,在弹出的窗口中修改代码模板:

 

    可以在value部分看到代码生成的脚本,如果你使用codesmith等代码生成工具写过模板,这段脚本就很容易理解了,只要自己修改下就可以了,例如,我把其中的第三行:[%visibility% ][%flags% ]%dataType% _%Code%[ = %InitialValue%];

这句改成:

private %dataType% _%Code%[ = %InitialValue%];

public %dataType% %Code%

{

       get

       {

              return _%Code%;

       }

       set

       {

              value = _%Code%;

       }

}

另外两个if分支中的也作相应的修改,再生成一次看看,getset函数都有了。

    
     C#
的代码模板是PowerDesigner的安装目录下的Resource Files\Object Languages目录下的csharp.xol文件,打开后可以看到实际上是一个xml文件,这样你就可以自己定义代码生成的模板了。

 

    上面是使用PowerDesigner直接生成C#代码,为了通用性考虑,首选xml,可以给对象模型的语言选择xml Schema,用对象模型生成一个xsd文件,然后自己来写一个代码生成器,我作了一个很简单的例子,有兴趣的朋友可以看看。

PowerDesigner生成的xsd文件内容:

<?xml version = "1.0" ?>

<xsd:schema name="ObjectOrientedModel_1.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 

  <xsd:element name="Customers">

   <xsd:element name="ID" type="int"/>

   <xsd:element name="Name" type="string"/>

   <xsd:element name="Address" type="string"/>

  </xsd:element>

 

  <xsd:element name="Orders">

   <xsd:element name="ID" type="int"/>

   <xsd:element name="CustomerID" type="int"/>

   <xsd:element name="OrderNumber" type="int"/>

  </xsd:element>

 

</xsd:schema>

 

我又使用了一个xml文件作生成器的配置config.xml文件内容:

<?xml version="1.0" ?>

<template>

       <xsdfile name='Z:\study\cs\ObjectOrientedModel_1.xsd'/>

       <outputdirectory name='z:/csfile'/>

       <namespace name = 'dahuzizyd'/>

</template>


我机器上的开发环境和
VS.net有冲突,只好用python写了一个,但是只有不到50行,应该是比较容易读懂的:

from xml.dom import minidom

import os

 

#get config

configdoc 
= minidom.parse('config.xml')

 

xsdfilename 
= configdoc.getElementsByTagName('xsdfile')[0].attributes['name'].value

namespace 
= configdoc.getElementsByTagName('namespace')[0].attributes['name'].value

outputdirectory 
= configdoc.getElementsByTagName('outputdirectory')[0].attributes['name'].value

 

# load xsd file

xsddoc 
= minidom.parse(xsdfilename)

basenode 
= xsddoc.childNodes[0]

 

#create .cs file

for node in basenode.childNodes:

       
if node.nodeType == node.ELEMENT_NODE :

              filename 
= node.attributes["name"].value

 

              f 
= open(outputdirectory + filename + '.cs','w')

              f.write(
'using System;\n')

              f.write(
'namespace ' + namespace + '\n')

              f.write(
'{\n\t')

              f.write(
'class ' + filename + '\n')

              f.write(
'\t{\n')

 

              nodeList 
= node.getElementsByTagName('xsd:element')

              

              
for elementNode in nodeList :

 

                     name 
=  elementNode.attributes["name"].value

              

                     
if elementNode.hasAttribute('type') :

                            elementType 
= elementNode.attributes["type"].value

                            

                            f.write(
'\t\tprivate ' + elementType + ' _' + name + ';\n\t\t')

                            f.write(
'public ' + elementType + ' ' + name + '\n\t\t{\n\t\t\t')

                            f.write(
'get { return _' + name + ';}\n\t\t\t')

                            f.write(
'set { _' +  name + '= value;}\n')

                            f.write(
'\t\t}\n')

                     

                     f.write(
'\n')

              

              f.write(
'\t}\n')

              f.write(
')')

              f.close()

 

 

Feedback

#1楼   回复  引用  查看    

2006-06-01 21:07 by 双鱼座      
我还以为说从数据库模型转代码呢

我的导入器支持PowerDesigner数据库模型,不过仅支持xml格式模型文件

#2楼[楼主]   回复  引用  查看    

2006-06-01 21:20 by Cure      
@双鱼座
我把摘要改了,这样看起来就不会让人误解了

#3楼   回复  引用  查看    

2006-06-02 09:02 by kid_li      
哈哈,原来PowerDesigner还有这功能,随便试了一下,挺好,还要感谢你的这篇文章。

#4楼   回复  引用  查看    

2006-06-02 09:40 by 努力学习的熊      
跟我们现在使用CodeSmith的想法一样,我们是制作了一个根据数据库自选字段生成对象的XML的一个工作,然后使用CodeSmith生成其他的代码,看楼主这个好像也要自己编写模板代码,感觉不如CodeSmith好用,起码CodeSmith能支持使用一些C#的类,并在编写代码时有智能提示,建议楼主看下:)

#5楼   回复  引用  查看    

2006-06-02 12:34 by 发芽的豆子      
赞!

#6楼[楼主]   回复  引用  查看    

2006-06-05 08:59 by Cure      
@努力学习的熊
我这样做的目的就是完全摆脱对数据库结构的依赖,而直接从领域模型来进行代码生成,所以会考虑和PowerDesigner等工具结合在一起。

#7楼   回复  引用  查看    

2006-06-12 20:57 by dotnetcoding      
http://www.dotnetcoding.net">http://www.dotnetcoding.net

系统运用分层原理和组件原理,将所有的MIS管理系统划分为用户界面层,业务规则层,数据访问层和数据库层.每一下层为上层提供支持,一般不跨层访问;同时结合现在一些已经成熟的设计框架,设计模式和构件模式,将一个解决方案分解为6个Project.分别是通用类库, 通用控件库,数据访问工程,业务规则工程,项目专用控件工程,UI界面工程.整个方案根据已经设计好的数据库自动生成,在生成的过程种可以灵活的定义生成参数.

系统实现了比较完整的O-R映射.数据库中的所有逻辑对象表,列,字段,主键,外键,Null,Default,唯一索引都在类里得到了体现,同时还支持代码表,代码列,自增长机制.

系统支持完整的数据操作功能,支持带事务功能的数据操作,提供数据自动装载功能,有很强的数据查询功能.

系统采用强类型来进行代码的生成,并且对最终开发人员的强类型支持很好,从而减少在编码过程中引入的错误,为编写高质量的代码提供了强有力的支持.

系统也比较充分的考虑了变更与维护的需要,在数据库设计发生变化的情况下,只要在已有工程的基础上重新生成一遍,系统就会自动合并最终开发编写的代码到生成的代码中,使系统的变更变的很容易.

UI界面层按到组件原则来进行代码的自动生成.自动生数据编辑,数据显示控件,页面组合组件,并采用控件和CSS技术,由于采用了这些组件技术,使得最终开发人员可以很方便的变更自动生成的界面样式; UI界面应用MVC模式,将这个UI界面代码部分分为三部分:视图部分,模型部分和控制,自动生成Data Source属性来完成view和Moudle的相互映射;并且能按照功能组生成菜单, 同时系统能自动完成null, PK ,UK等基本的数据检验和基于单表数据的增删查改等基础功能.



此系统还提供了文档生成,数据库迁移与转换及部分设计有关的功能

现在此平台支持多种数据访问框架(三层框架, PetShop框架,工厂框架, WebServerice框架)

支持Windows , Web两种应用类型

支持VB.net , c#.Net两种开发语言

支持ServerSql, Oracle, Access,等多种数据库, 并且支持用SqlServer数据库来进行数据模式的设计,而实际开发运行数据库是其他数据库的情况, 开发的应用可以非常轻松的变换数据库.

本系统的应用范围:有数据库访问功能的.net应用

应用前提:需要有已经设计好的数据库

采用此平台来开发信息管理系统, 能够直接将设计转化为代码,并支持系统的重构;最终开发人员一般只需要在业务规则层扩展相关业务规则的编码,对自动生成的界面进行少量的调整,在UI界面工程里添加少量的控制代码.

采用此开发平台,能够在公司范围内不断的积累开发技能和经验,极大的提高开发效率,规范开发,提高开发质量.

搜索关键字: dotnet ,coding, ORM,MVC,strong type auto code, code generator, vb.net ,c#.net, oracle, Sqlserver,持久对象,多层模型

代码生成,代码工厂,实体关系映射,


#8楼[楼主]   回复  引用  查看    

2006-06-13 09:01 by Cure      
我也在文章开头写了,要区别对待对象模型和关系模型的匹配和不匹配两种情况。虽然直接从关系模型进行代码生成是可以使用的,但是我认为这样作并不是最正确的。

#9楼   回复  引用  查看    

2006-08-28 20:44 by 昆仑居士      
几乎所有的领域模型设计器都支持代码生成的,并不限于PowerDesign,但这与单独的代码生成器并不矛盾。单独的代码生成器是对领域模型设计器的补充。
因为在数据库里建立正确严格的数据模型,是软件开发的一个不可逾越的步骤,而在领域模型里建立正确,严格的数据模型不一定是必须的。领域模型往往是在更高层次上进行数据模型的设计,与编码时用的数据模型可能存在一定的差异,而数据库里的数据模型必然要与代码编写严格同步。

#10楼[楼主]   回复  引用  查看    

2006-08-31 12:43 by Cure      
@ 昆仑居士
我在这里要强调的是PowerDesinger提供了可订制生成模板的功能,而可订制功能正是代码生成器的目标之一。单独的代码生成器的成功例子也很多了,codesmith,MyGenerator等。

至于为什么要从领域模型生成代码,我想文章开头也说了,要区分领域模型和数据库模型匹配和不匹配的情况,匹配的时候,我们可以简单的认为数据库模型就是领域模型,直接从数据库模型生成就可以了,但是不匹配的时候,领域模型真正反映业务逻辑,至于数据怎么持久化,现在有N多的框架在做这些事情,我们要Coding的时候要关注的就是领域模型了。

如果说一定要从数据库模型生成代码,这也无可厚非,但是这样仅限于小型的,业务不太复杂的情况。所以,应该同时提供从领域模型来生成。


#11楼   回复  引用  查看    

2006-09-22 13:00 by 林子      
8错

#12楼   回复  引用    

2007-06-26 14:20 by dsfasdf[未注册用户]
http://www.so520.cn
http://go.so520.cn
http://www.cnjjj.cn

#13楼   回复  引用  查看    

2008-04-16 16:13 by 毁于随      
参考这个,将默认的代码生成加上了对泛型的Using.



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 415209




相关文章:

相关链接: