按Sybase的PowerDesigner工具设计的数据库模型 ---> 解析生成能兼容多种数据库的相应的C#底层代码

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

先有设计,后有代码,改设计总比改代码更容易一些,改设计的成本更低廉,软件也要按图纸施工,没有图纸的建筑物,将来也不好维护,没有数据库设计的软件更怎么可能好维护呢?

 

1:总希望自己的程序能兼容多种数据库,那就尽量用多种数据库都兼容的数据库字段类型来设计表结构。

 

2:将数据库中的表结构能对应到C#的类型里,然后能读取相应的实体字段、按实体的属性写入数据库表中。

 

3:为了测试大容量并发插入表的测试,设计了2个表结构,其中一个用GUID做主键,生成唯一主键,另一个用自增量或者序列做主键。

 

4:代码生成器里,设置了数据库类型与C#的数据类型的对应关系设置及默认值的关系设置等。

代码
         ///   <summary>
        
///  数据库类型映射关系(数据库类型、C#类型、默认值、读取函数)
        
///   </summary>
         string  [,]  DataTypeMapping  =  {
                                    {
" NVARCHAR " , " String " " null " " ToString " },
                                    {
" CHAR " , " String " " null " " ToString " },
                                    {
" INT " , " int " " 0 " " ToInt " },
                                    {
" INTEGER " , " int " " 0 " " ToInt " },
                                    {
" NUMERIC " , " Double " " 0 " " ToDouble " },
                                    {
" FLOAT " , " Double " " 0 " " ToDouble " },
                                    {
" DATE " , " DateTime? " " null " " ToDateTime " },
                                    {
" BLOB " , " Byte[] " " null " " ToByte " },
                                    {
" BFILE " , " Byte[] " " null " " ToByte " },
                                    {
" IMAGE " , " Byte[] " " null " " ToByte " }
                                };

        
///   <summary>
        
///  获取字段的类型
        
///   </summary>
        
///   <param name="fieldDataType"> 数据库字段类型 </param>
        
///   <returns> 类型 </returns>
         private   string  GetDataType( string  fieldDataType,  ref   string  defaultValue)
        {
            
//  这是默认值
             string  returnValue  =   typeof ( string ).Name.ToString();
            defaultValue 
=   " null " ;
            
//  这个是差找对比
             for  ( int  i  =   0 ; i  <  DataTypeMapping.GetLength( 0 ); i ++ )
            {
                
if  (fieldDataType.IndexOf(DataTypeMapping[i,  0 ])  >=   0 )
                {
                    returnValue 
=  DataTypeMapping[i,  1 ];
                    defaultValue 
=  DataTypeMapping[i,  2 ];
                    
//  不循环了,提高效率
                     break ;
                }
            }   
            
return  returnValue;
        }

        
private   string  GetDataType( string  fieldDataType)
        {
            
//  这是默认值
             string  returnValue  =   typeof ( string ).Name.ToString();
            
//  这个是差找对比
             for  ( int  i  =   0 ; i  <  DataTypeMapping.GetLength( 0 ); i ++ )
            {
                
if  (fieldDataType.IndexOf(DataTypeMapping[i,  0 ])  >=   0 )
                {
                    returnValue 
=  DataTypeMapping[i,  1 ];
                    
//  不循环了,提高效率
                     break ;
                }
            }
            
return  returnValue;
        }

        
private   string  GetColumnDataType(XmlNode xmlNode,  string  columnName)
        {
            
string  fieldDataType  =   string .Empty;
            
for  ( int  i  =   0 ; i  <  xmlNode.ChildNodes.Count; i ++ )
            {
                
if  (((XmlNode)xmlNode.ChildNodes[i]).LocalName.Equals( " Columns " ))
                {
                    
for  ( int  j  =   0 ; j  <  xmlNode.ChildNodes[i].ChildNodes.Count; j ++ )
                    {
                        
string  field  =  xmlNode.ChildNodes[i].ChildNodes[j].ChildNodes[ 2 ].InnerText;
                        
if  (field.Equals(columnName))
                        {
                            
for  ( int  z  =   0 ; z  <  xmlNode.ChildNodes[i].ChildNodes[j].ChildNodes.Count; z ++ )
                            {
                                
if  (xmlNode.ChildNodes[i].ChildNodes[j].ChildNodes[z].LocalName.Equals( " DataType " ))
                                {
                                    
//  字段类型大写
                                    fieldDataType  =  xmlNode.ChildNodes[i].ChildNodes[j].ChildNodes[z].InnerText.ToUpper();
                                    
break ;
                                }
                            }
                            
break ;
                        }
                    }
                    
break ;
                }
            }
            
return  GetDataType(fieldDataType);
        }

        
private   string  GetConvertFunction( string  fieldDataType)
        {
            
//  这是默认值
             string  returnValue  =   " ToString " ;
            
//  这个是差找对比
             for  ( int  i  =   0 ; i  <  DataTypeMapping.GetLength( 0 ); i ++ )
            {
                
if  (fieldDataType.IndexOf(DataTypeMapping[i,  0 ])  >=   0 )
                {
                    returnValue 
=  DataTypeMapping[i,  3 ];
                    
//  不循环了,提高效率
                     break ;
                }
            }
            
return  returnValue;
        }

 

 

5:接下来需要用代码生成器生成相应的代码,这时候比较麻烦的事情有以下几个:

A:guid做主键时,为了兼容多种数据库,用了字符类型字段,用自增量时,主键为整数类型,这里需要有一定的技术水平需要处理一下。

B:用自增量做主键时,不同的数据库的处理方式不一样,这时候需要考虑写同一套代码,能兼容多种数据库的问题,程序的写法是一样同时能能支持多种数据库。

 

6:为了测试多种数据库上的兼容性,现在以 Oracle、SQLServer 为主要目标来进行测试,创建数据库的脚本如下:

UserByGUID.Oracle.SQL (Oracle按GUID为主键模式)

代码
--  Create table
create table USERBYGUID
(
  ID                 NVARCHAR2(
50 ),
  FULLNAME           NVARCHAR2(
50 ),
  SALARY             NUMBER(
10 , 2 default   0 ,
  AGE                NUMBER(
2 default   0 ,
  BIRTHDAY           DATE,
  PHOTO              BLOB,
  ALLOWEDIT          NUMBER(
1 default   1 ,
  ALLOWDELETE        NUMBER(
1 default   1 ,
  ENABLED            NUMBER(
1 default   1 ,
  DELETEMARK         NUMBER(
1 default   0 ,
  DESCRIPTION        NVARCHAR2(
200 ),
  CREATEDATE         DATE 
default  sysdate,
  CREATEUSERID       NVARCHAR2(
50 ),
  CREATEUSERREALNAME NVARCHAR2(
50 ),
  MODIFYDATE         DATE 
default  sysdate,
  MODIFYUSERID       NVARCHAR2(
50 ),
  MODIFYUSERREALNAME NVARCHAR2(
50 )
);

 

UserByInt.Oracle.SQL (Oracle按序列为主键模式)

代码
--  Create sequence 
create sequence SEQ_USERBYINT
minvalue 
1
maxvalue 
999999999999999999999999999
start with 
21
increment by 
1
cache 
20 ;

--  Create table
create table USERBYINT
(
  ID                 NUMBER,
  FULLNAME           NVARCHAR2(
50 ),
  SALARY             NUMBER(
10 , 2 default   0 ,
  AGE                NUMBER(
2 default   0 ,
  BIRTHDAY           DATE,
  PHOTO              BLOB,
  ALLOWEDIT          NUMBER(
1 default   1 ,
  ALLOWDELETE        NUMBER(
1 default   1 ,
  ENABLED            NUMBER(
1 default   1 ,
  DELETEMARK         NUMBER(
1 default   0 ,
  DESCRIPTION        NVARCHAR2(
200 ),
  CREATEDATE         DATE 
default  sysdate,
  CREATEUSERID       NVARCHAR2(
50 ),
  CREATEUSERREALNAME NVARCHAR2(
50 ),
  MODIFYDATE         DATE 
default  sysdate,
  MODIFYUSERID       NVARCHAR2(
50 ),
  MODIFYUSERREALNAME NVARCHAR2(
50 )
);

 

UserByGUID.SQLServer.SQL (SQLServer按GUID为主键模式)

代码
CREATE TABLE [dbo].[UserByGUID](
    [Id] [nvarchar](
50 )  NOT NULL,
    [FullName] [nvarchar](
50 ) NULL,
    [Salary] [numeric](
10 2 ) NULL DEFAULT (( 0 )),
    [Age] [
int ] NULL DEFAULT (( 0 )),
    [Birthday] [smalldatetime] NULL DEFAULT (getdate()),
    [Photo] [image] NULL,
    [AllowEdit] [
int ] NULL DEFAULT (( 1 )),
    [AllowDelete] [
int ] NULL DEFAULT (( 1 )),
    [Enabled] [
int ] NULL DEFAULT (( 1 )),
    [DeleteMark] [
int ] NULL DEFAULT (( 0 )),
    [Description] [nvarchar](
50 )  NULL,
    [CreateDate] [smalldatetime] NULL DEFAULT (getdate()),
    [CreateUserId] [nvarchar](
50 )  NULL,
    [CreateUserRealname] [nvarchar](
50 )  NULL,
    [ModifyDate] [smalldatetime] NULL DEFAULT (getdate()),
    [ModifyUserId] [nvarchar](
50 )  NULL,
    [ModifyUserRealname] [nvarchar](
50 )  NULL,
 CONSTRAINT [PK_USERBYGUID] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (IGNORE_DUP_KEY 
=  OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

 

UserByInt.SQLServer.SQL (SQLServer自增量方式)

代码
CREATE TABLE [dbo].[UserByInt](
    [Id] [
int ] IDENTITY( 1 , 1 ) NOT NULL,
    [FullName] [nvarchar](
50 ) NULL,
    [Salary] [numeric](
10 2 ) NULL DEFAULT (( 0 )),
    [Age] [
int ] NULL DEFAULT (( 0 )),
    [Birthday] [smalldatetime] NULL DEFAULT (getdate()),
    [Photo] [image] NULL,
    [AllowEdit] [
int ] NULL DEFAULT (( 1 )),
    [AllowDelete] [
int ] NULL DEFAULT (( 1 )),
    [Enabled] [
int ] NULL DEFAULT (( 1 )),
    [DeleteMark] [
int ] NULL DEFAULT (( 0 )),
    [Description] [nvarchar](
50 ) NULL,
    [CreateDate] [smalldatetime] NULL DEFAULT (getdate()),
    [CreateUserId] [nvarchar](
50 ) NULL,
    [CreateUserRealname] [nvarchar](
50 ) NULL,
    [ModifyDate] [smalldatetime] NULL DEFAULT (getdate()),
    [ModifyUserId] [nvarchar](
50 ) NULL,
    [ModifyUserRealname] [nvarchar](
50 ) NULL,
 CONSTRAINT [PK_USERBYINT] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (IGNORE_DUP_KEY 
=  OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

 

 

7:用代码生成器,生成相关的类代码:

 

8:代码复制到工程文件里的效果如下:

 

9:编写自动化测试程序如下

代码
// ------------------------------------------------------------
//  All Rights Reserved , Copyright (C) 2010 , Jirisoft , Ltd. 
// ------------------------------------------------------------

using  System;
using  System.IO;

namespace  DotNet.Web.Permission
{
    
using  DotNet.Utilities;

    
///   <remarks>
    
///  SQLServerExample
    
///  多种数据库兼容的实现方法,只写一套程序在多种数据库上执行例子程序
    
///  
    
///  修改纪录
    
///  
    
///     版本:1.0 2010.06.20    JiRiGaLa    写好例子程序方便别人学习。
    
///     
    
///  版本:1.0
    
///   <author>
    
///          <name> JiRiGaLa </name>
    
///          <date> 2010.06.20 </date>
    
///   </author>  
    
///   </remarks>
     public   partial   class  SQLServerExample : System.Web.UI.Page
    {
        
protected   void  Page_Load( object  sender, EventArgs e)
        {
            
string  id  =   string .Empty;
            
//  按GUID方式添加数据
            id  =   this .AddEntityByGUID();
            Page.Response.Write(
" :GUID: "   +  id  +   " <br> " );
            
//  按自增量方式添加数据
            id  =   this .AddEntityByIdentity();
            Page.Response.Write(
" :Identity: "   +  id  +   " <br> " );
        }

        
///   <summary>
        
///  读取图片文件
        
///   </summary>
        
///   <param name="fileName"> 文件名 </param>
        
///   <returns> 字节 </returns>
         private   byte [] GetFile( string  fileName)
        {
            FileStream fileStream 
=   new  FileStream(fileName, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader 
=   new  BinaryReader(fileStream);
            
byte [] file  =  binaryReader.ReadBytes((( int )fileStream.Length));
            binaryReader.Close();
            fileStream.Close();
            
return  file;
        }

        
///   <summary>
        
///  添加实体
        
///   </summary>
        
///   <returns> 主键 </returns>
         private   string  AddEntityByGUID()
        {
            
//  这个是管理器
            UserByGUIDManager userByGUIDManager  =   new  UserByGUIDManager();
            
//  不要自增量
            
//  userByGUIDManager.Identity = false;
            
//  这个是实体
            UserByGUIDEntity userByGUIDEntity  =   new  UserByGUIDEntity();
            userByGUIDEntity.Id 
=  BaseBusinessLogic.NewGuid();
            userByGUIDEntity.FullName 
=   " 吉日嘎拉 " ;
            userByGUIDEntity.Salary 
=   15000.00 ;
            userByGUIDEntity.Age 
=   33 ;
            userByGUIDEntity.AllowDelete 
=   1 ;
            userByGUIDEntity.AllowEdit 
=   1 ;
            userByGUIDEntity.Birthday 
=   new  DateTime( 1978 5 19 );
            userByGUIDEntity.DeleteMark 
=   0 ;
            userByGUIDEntity.Enabled 
=   1 ;
            userByGUIDEntity.Photo 
=   this .GetFile( @" C:\Users\jirigala\Pictures\01.jpg " );
            
//  这里是添加操作
             return  userByGUIDManager.Add(userByGUIDEntity);
        }

        
///   <summary>
        
///  添加实体
        
///   </summary>
        
///   <returns> 主键 </returns>
         private   string  AddEntityByIdentity()
        {
            
//  这个是管理器
            UserByIntManager userByIntManager  =   new  UserByIntManager();
            
//  是要自增量
            
//  userByIntManager.Identity = true;
            
//  不用返回
            
//  userByIntManager.ReturnId = false;
            
//  这个是实体
            UserByIntEntity userByIntEntity  =   new  UserByIntEntity();
            userByIntEntity.FullName 
=   " 吉日嘎拉 " ;
            userByIntEntity.Salary 
=   15000.00 ;
            userByIntEntity.Age 
=   33 ;
            userByIntEntity.AllowDelete 
=   1 ;
            userByIntEntity.AllowEdit 
=   1 ;
            userByIntEntity.Birthday 
=   new  DateTime( 1978 5 19 );
            userByIntEntity.DeleteMark 
=   0 ;
            userByIntEntity.Enabled 
=   1 ;
            userByIntEntity.Photo 
=   this .GetFile( @" C:\Users\jirigala\Pictures\01.jpg " );
            
//  这里是添加操作
             return  userByIntManager.Add(userByIntEntity,  true );
        }
    }
}

 

 

10:同样的程序,修改配置文件,连接到Oracle数据库上,GUID方式生成主键、徐列生成主键完全运行正常,惊喜一下。

代码
<? xml version = " 1.0 " ?>
< configuration >
  
< appSettings >
    
< add key = " RunMode "  value = " Local " />
    
< add key = " ServiceFactory "  value = " ServiceFactory " />
    
< add key = " ServicePath "  value = " DotNet.Service " />

    
< add key = " DbHelperAssmely "  value = " DotNet.DbUtilities " />
    
< add key = " DataBaseType "  value = " Sqlserver " />
    
< add key = " DbHelperClass "  value = " DotNet.DbUtilities.SqlHelper " />
    
< add key = " UserCenterConnection "  value = " Server=JIRIGALA-PC;Database=UserCenterV30;Uid=sa;Pwd=sa; " />

    
<!--
    
< add key = " DataBaseType "  value = " Oracle " />
    
< add key = " DbHelperClass "  value = " DotNet.DbUtilities.OracleHelper " />
    
< add key = " UserCenterConnection "  value = " Data Source = FDAZTC;user id = ztc;password = ztc " />
    
-->

< add key = " BusinessDBConnection "  value = " Data Source=JIRIGALA-PC\SQLEXPRESS;Initial Catalog=ConvenienceServices;Integrated Security=SSPI; " />
    
< add key = " CustomerCompanyName "  value = " 权限学习 " />
    
< add key = " SoftName "  value = " Water " />
    
< add key = " SoftFullName "  value = " 通用权限管理系统 " />
    
< add key = " CompanyFullName "  value = " 杭州吉日软件 " />
    
< add key = " Update "  value = " 2010.06.20 " />
    
< add key = " BugFeedback "  value = " JiRiGaLa_Bao@hotmail.com " />
  
</ appSettings >
  
< connectionStrings >
    
< add name = " Sqlserver "  connectionString = " Server=JIRIGALA-PC;Database=UserCenterV30;Uid=sa;Pwd=sa; "  providerName = " DotNet.DbUtilities.SqlHelper " />
  
</ connectionStrings >
  
< system.web >
    
< compilation debug = " true " >
    
</ compilation >
    
< authentication mode = " Windows " />
    
< customErrors mode = " Off " />
  
</ system.web >
</ configuration >

 

 

11:PowerDesigner设计的PDM文件下载,请在此下载

/Files/jirigala/CodeBuilder.pdm.rar

 

12:完整的例子程序下载,请在此下载,若有缺少的DLL引用,可以在从目录DotNet.Web.Permission\Resource\External 里进行重新饮用

/Files/jirigala/DotNet.Web.Permission.rar

 

13:在淘宝网店地址 http://shop59297253.taobao.com/ 上购买相应的功能软件,此强大的代码生成器仅销售RMB:100元、服务后,请添加技术支持QQ2520 – 56973,索取相应的程序源码、设计文档等等。

 


本文转自jirigala_bao 51CTO博客,原文链接:http://blog.51cto.com/jirigala/806795

相关文章
|
6天前
|
Java
Java中ReentrantLock释放锁代码解析
Java中ReentrantLock释放锁代码解析
23 8
|
13天前
|
SQL 数据可视化 关系型数据库
轻松入门MySQL:深入探究MySQL的ER模型,数据库设计的利器与挑战(22)
轻松入门MySQL:深入探究MySQL的ER模型,数据库设计的利器与挑战(22)
|
22天前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
165 1
|
22天前
|
存储 C# 容器
C变量数据类型深度解析:打造高效代码的基石
C变量数据类型深度解析:打造高效代码的基石
13 1
|
29天前
|
C# Windows
C#通过代码实现快捷键编辑
C#通过代码实现快捷键编辑
|
1月前
|
数据采集 Java 关系型数据库
Java代码高效连接数据库
Java代码高效连接数据库
16 2
|
1月前
|
存储 数据库 Python
用Python代码表示数据库
用Python代码表示数据库
14 0
|
26天前
|
关系型数据库 MySQL 数据库
rds安装数据库客户端工具
安装阿里云RDS的数据库客户端涉及在本地安装对应类型(如MySQL、PostgreSQL)的客户端工具。对于MySQL,可选择MySQL Command-Line Client或图形化工具如Navicat,安装后输入RDS实例的连接参数进行连接。对于PostgreSQL,可以使用`psql`命令行工具或图形化客户端如PgAdmin。首先从阿里云控制台获取连接信息,然后按照官方文档安装客户端,最后配置客户端连接以确保遵循安全指引。
78 1
|
22天前
|
存储 SQL 缓存
【软件设计师备考 专题 】数据库模型(概念模式、外模式、内模式)
【软件设计师备考 专题 】数据库模型(概念模式、外模式、内模式)
64 0
|
22天前
|
机器学习/深度学习 存储 Java
揭秘数组:数据结构的基石与代码实践解析
揭秘数组:数据结构的基石与代码实践解析
8 0

推荐镜像

更多