先有设计,后有代码,改设计总比改代码更容易一些,改设计的成本更低廉,软件也要按图纸施工,没有图纸的建筑物,将来也不好维护,没有数据库设计的软件更怎么可能好维护呢?
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] [p_w_picpath] 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] [p_w_picpath] 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元、服务后,请添加技术支持QQ:2520 – 56973,索取相应的程序源码、设计文档等等。
一步步教你如何用疯狂.NET架构中的通用权限系统 -- 如何控制用户显示的菜单权限
一步步教你如何用疯狂.NET架构中的通用权限系统 -- 在页面中的调用权限讲解
一步步教你如何用疯狂.NET架构中的通用权限系统 -- 数据集权限的调用权限讲解
一步步教你如何用疯狂.NET架构中的通用权限系统 -- 分级管理
一步步教你如何用疯狂.NET架构中的通用权限系统 -- 分级授权

疯狂.NET 通用权限设计 C\S后台管理,B\S前台调用源码样例程序×××之 --- 操作权限
疯狂.NET 通用权限设计 C\S后台管理,B\S前台调用源码样例程序×××之 --- 角色权限
疯狂.NET 通用权限设计 C\S后台管理,B\S前台调用源码样例程序×××之 --- 数据集权限

  

转载于:https://blog.51cto.com/2347979/447614

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

  1. PowerDesigner如何设计表之间的关联

    PowerDesigner如何设计表之间的关联 步骤/方法 在工具箱中找到参照关系工具: 由地区表到省份表之间拉参照关系,箭头指向父表,然后双击参照关系线,打开参照关系的属性: 在这里检查父表与子表是 ...

  2. 纸上原型设计 VS 桌面原型工具设计,你更喜欢谁?

    2019独角兽企业重金招聘Python工程师标准>>> 纸上原型设计,作为传统的原型设计方式,简单快速,成本低廉,为大部分设计师所喜爱.而桌面原型工具设计,作为伴随电脑科技发展而出现 ...

  3. sketch 将动图转换为json_开源 | Picasso:sketch设计稿智能解析工具

    开源二期项目专题系列(一) 1. 开源项目名称:Picasso 2. github地址: https://github.com/wuba/Picasso 3. 简介:Picasso是58同城推出的一款 ...

  4. 用PowerDesigner工具条不见的

    用PowerDesigner工具条不见的 tools-Customize toolbars里勾palette 就能出现 生成错误的时候可以吧CHECKMODEL关掉, posted on 2011-0 ...

  5. 【java毕业设计】基于java+BS的QQ屏幕截图工具设计与实现(毕业论文+程序源码)——屏幕截图工具

    基于java+BS的QQ屏幕截图工具设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+BS的QQ屏幕截图工具设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦. 文章目录: ...

  6. 【开源共享】全网最简单易用的imx6ull烧写工具设计初衷工作原理设计前的思考

    在线课堂:https://www.100ask.net/index(课程观看) 论  坛:http://bbs.100ask.net/(学术答疑) 开 发 板:https://100ask.taoba ...

  7. 【php毕业设计】基于php+mysql+apache的网络数据包分析工具设计与实现(毕业论文+程序源码)——网络数据包分析工具

    基于php+mysql+apache的网络数据包分析工具设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于php+mysql+apache的网络数据包分析工具设计与实现,文章末尾附有本毕业设 ...

  8. 网页原型设计工具设计_设计工具用完了

    网页原型设计工具设计 by Colm Tuite 通过Colm Tuite 设计工具已超出预期. 这是我们如何修复它们的方法. (Design tools are running out of tra ...

  9. 公章逼真教程_30多种逼真的小工具设计Photoshop教程

    Photoshop确实是设计师的最好朋友. 它用于设计几乎所有内容,包括图标,网站,照片增强功能等等,并且列表不胜枚举. 实际上,在我们较早的文章" Apple令人惊叹的概念设计 " ...

最新文章

  1. 让开源解读“甲骨文”--RHEL5.3部署安装Oracle Database10g Release2
  2. SAN,NAS区别的联系
  3. python挂机脚本阴阳师_Python简单实现阴阳师挂机脚本
  4. php 内核开发_深入理解PHP7内核之Reference
  5. 查看ie保存的表单_小学信息技术gt;搜索保存网页教师资格证面试模板
  6. 小身材大用途,用PrimusUI驾驭你的页面
  7. Flutter之BottomSheet
  8. Log4cpp 配置文件格式说明
  9. java 正则表达式 提取ip_使用正则表达式从字符串中提取IP地址
  10. 物联网工程导论 简单整理
  11. rax调用微信小程序原生事件
  12. 推荐系统序列化建模总结
  13. 《计算机网络 自顶向下方法》答案(第八章)(重制版)
  14. excel 将图片的链接URL 显示为图片 转
  15. 事件推送网关:让cmdb告别“花瓶”
  16. Apache ShardingSphere 5.0.0-alpha版本发布
  17. 软件之聊天工具:QQ,MSN,Google talk,Skype, Lync
  18. 汇川AM401非标准协议通讯socket_client
  19. 【Linux】树莓派控制光强传感器(C、python手把手教学)
  20. 996 与 郭琪 | 北漂生活 | 裙子戏言

热门文章

  1. 华为c语言中static的作用,C语言编程规范(华为、林锐、MISRAC).pdf
  2. linux编译内核支持pam,linux编译内核make menuconfig报错解决办法
  3. Java Elasticsearch 使用
  4. c语言增加动态分配的存储空间吗,C语言 关于内存动态分配问题
  5. linux 认证 转发,一种基于Linux系统实现路由器的portal认证报文转发方法和装置
  6. opencv matlab配置,Matlab下运行c++程序的配置(包含opencv的c++程序)
  7. Bellman_Ford算法(求一个点到任意一点的最短距离)
  8. Python中的列表(list)
  9. android自定义工具栏,Android工具栏中的自定义图标
  10. 如何监控impala的数据_impala数据库的函数