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

简介:

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

 

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

相关文章
|
3天前
|
运维 安全 关系型数据库
参加数据库管理工具DAS训练营,赢取国潮保温杯和阿里云定制双肩包!
本训练营带您简单了解数据库自治与云安全服务,数据库自治服务提供云上RDS、PolarDB、NoSQL、ADB等数据库7*24小时异常检测、SQL自优化、安全合规审计、弹性伸缩、数据自治、锁分析等亮点功能。一站式自动化、数字化DAS集成平台,助力您畅享DBA运维智能化。
|
24天前
|
存储 缓存 关系型数据库
鱼和熊掌如何兼得?一文解析RDS数据库存储架构升级
阿里云RDS率先推出新型存储类型通用云盘,提供低延迟、低成本、高持久性的用户体验。
鱼和熊掌如何兼得?一文解析RDS数据库存储架构升级
|
29天前
|
开发框架 .NET 编译器
C# 10.0中Lambda表达式的改进:更简洁、更灵活的代码编写体验
【1月更文挑战第21天】随着C#语言的不断发展,Lambda表达式作为一种简洁、高效的函数式编程工具,在C# 10.0中迎来了重要的改进。本文将详细探讨C# 10.0中Lambda表达式的新特性,包括参数类型的推断增强、自然类型的Lambda参数以及Lambda表达式的属性改进等。这些改进不仅简化了Lambda表达式的编写过程,还提升了代码的可读性和灵活性,为开发者带来了更优质的编程体验。
|
1月前
|
C# 开发者
C# 10.0中的文件范围命名空间:简化代码组织的新方式
【1月更文挑战第18天】C# 10.0引入了文件范围的命名空间,这是一种新的语法糖,用于更简洁地组织和管理代码。文件范围命名空间允许开发者在每个文件的基础上定义命名空间,而无需显式使用花括号包裹整个文件内容。本文将深入探讨文件范围命名空间的工作原理、使用场景以及它们为C#开发者带来的便利。
|
2天前
|
SQL 关系型数据库 MySQL
在OceanBase数据库中,mysqldump工具是可以用于数据备份的
【2月更文挑战第2天】在OceanBase数据库中,mysqldump工具是可以用于数据备份的
12 6
|
3天前
|
SQL 安全 Devops
一个简单的代码拼写错误导致17个生产数据库被删!微软Azure DevOps宕机10小时始末
一个简单的代码拼写错误导致17个生产数据库被删!微软Azure DevOps宕机10小时始末
|
5天前
|
SQL 自然语言处理 数据管理
观点 | 大模型与数据库
本文初步将探讨大模型为数据库带来的机遇,以及数据库为大模型带来的价值,并展望了未来数据库与大模型的发展趋势。
观点 | 大模型与数据库
|
17天前
|
编解码 人工智能 算法
Google Earth Engine(GEE)——高度可扩展的时间自适应反射率融合模型(HISTARFM)数据库
Google Earth Engine(GEE)——高度可扩展的时间自适应反射率融合模型(HISTARFM)数据库
10 0
|
19天前
|
SQL 数据库
数据库视图的超详细解析📖
数据库视图的超详细解析📖
10 0
|
19天前
|
SQL 监控 关系型数据库
数据库日志解析:深入了解MySQL中的各类日志
数据库日志解析:深入了解MySQL中的各类日志
45 0

热门文章

最新文章

推荐镜像

更多