一直想写一个自己的代码生成器,但是因为工作事情多,一直搁置下来,最近下决心终于利用下班时间写完了,现在分享给有需要的朋友,代码生成器集成EasyDBUtility数据库访问帮助类,暂时只支持sqlserver数据库,界面如下

部分代码如下

    /// <summary>
/// 生成sqlserver相关代码
/// </summary>
public class SqlServer
{
//获取所有数据库名称
public const string Get_DataBaseName_SQL = "SELECT Name FROM Master..SysDatabases where Name not in('master','model','msdb','tempdb') ORDER BY Name";
//获取指定数据库中所有表名
public const string Get_Tables_SQL = "SELECT Name FROM [{0}]..SysObjects Where XType='U' ORDER BY Name";
//获取指定数据库中所有视图
public const string Get_Views_SQL = "SELECT Name FROM [{0}]..SysObjects Where XType='V' ORDER BY Name";
//获取指定数据库中所有存储过程
public const string Get_Procedures_SQL = "SELECT Name FROM [{0}]..SysObjects Where XType='P' ORDER BY Name";
//获取指定表或视图中的所有列信息
public const string Get_Columns_SQL = "select a.name,b.name typeName,a.is_identity,a.is_nullable from sys.columns a " +
"left join sys.types b on a.user_type_id=b.user_type_id where a.object_id=object_id('{0}') order by column_id";
//获取指定列的数据类型
public const string Get_Type_Name_SQL = "SELECT type_name(user_type_id) as [type_name] FROM sys.columns where [object_id] = object_id('{0}') and [name] = '{1}'";
//获取指定表所有列的说明
public const string Get_Columns_Description_SQL = "SELECT objname as ColumnName,[value] as ColumnDescription FROM ::fn_listextendedproperty('MS_Description', 'user', 'dbo', 'table', '{0}', 'column', DEFAULT)";
//获取指定表中主键列名
public const string GetPKeys_SQL = "Declare @objectid int;Set @objectid=object_id('{0}');Select col_name(@objectid,colid) " +
"From sysobjects as o Inner Join sysindexes as i On i.name=o.name Inner Join sysindexkeys as k On k.indid=i.indid " +
"Where o.xtype = 'PK' and parent_obj=@objectid and k.id=@objectid"; /// <summary>
/// 生成业务逻辑层代码
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="connectionString">数据库连接字符串</param>
/// <param name="paramsData">生成参数</param>
/// <returns></returns>
public static string CreateBLL(string tableName, string connectionString, ParamsData paramsData)
{
string primaryKeyName = string.Empty;//主键名称
string primaryKeyTypeName = string.Empty;//主键数据类型 SqlHelper helper = new SqlHelper(connectionString);
helper.AutoClose = false;
//获取表的主键列名称
helper.CreateCommand(string.Format(GetPKeys_SQL, tableName));
object primaryKeyObj = helper.ExecuteScalar();
if (primaryKeyObj != null)
{
primaryKeyName = primaryKeyObj.ToString();
helper.CommandText(string.Format(Get_Type_Name_SQL, tableName, primaryKeyName));
primaryKeyTypeName = helper.ExecuteScalar().ToString();
}
else
{
//获取表的所有列信息,找出自增列作为主键字段
helper.CommandText(string.Format(SqlServer.Get_Columns_SQL, tableName));
IList<ColumnsData> columnList = helper.ExecuteReader<ColumnsData>();
ColumnsData columnsData = (from col in columnList where col.Is_identity == true select col).FirstOrDefault();
if (columnsData != null)
{
primaryKeyName = columnsData.Name;
primaryKeyTypeName = columnsData.TypeName;
}
}
helper.Close(); if (string.IsNullOrEmpty(primaryKeyName) || string.IsNullOrEmpty(primaryKeyTypeName))
{
throw new Exception("在表“" + tableName + "”中没有找到主键或自增列,无法生成BLL代码!请设置表的主键或自增列后再重试!");
} string deletePrefixOfTableName = frmMain.GetDeleteThePrefixTheTableName(tableName, paramsData);//生成的类名称
string parameterName = primaryKeyName.Substring(, ).ToLower() + primaryKeyName.Substring();//方法中传递的主键参数名称 StringBuilder bll = new StringBuilder();
bll.Append("using System.Collections.Generic;\r\n");
if (paramsData.Architecture == Architecture.反射工厂模式)
bll.Append("using " + paramsData.FactoryNamespace + ";\r\n");
bll.Append("using " + paramsData.IDALNamespace + ";\r\n");
bll.Append("using " + paramsData.ModelNamespace + ";\r\n\r\n");
bll.Append("namespace " + paramsData.BLLNamespace + "\r\n");
bll.Append("{\r\n ");
bll.Append("public class " + deletePrefixOfTableName + paramsData.BLLSuffix + "\r\n ");
bll.Append("{\r\n "); if (paramsData.Architecture == Architecture.反射工厂模式)
{
bll.Append("private static readonly I" + deletePrefixOfTableName + " dal = DataAccess.CreateInstance<I" + deletePrefixOfTableName + ">(\""
+ deletePrefixOfTableName + paramsData.DALSuffix + "\");\r\n\r\n");
}
else if (paramsData.Architecture == Architecture.简单三层)
{
bll.Append("private static readonly " + deletePrefixOfTableName + paramsData.DALSuffix + " dal = new " + deletePrefixOfTableName + paramsData.DALSuffix + "();\r\n\r\n");
} //新增方法
if (paramsData.CreateInsertMethod)
{
bll.Append(" public bool " + paramsData.InsertMethodName + "(" + deletePrefixOfTableName + paramsData.ModelSuffix + " data)\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.InsertMethodName + "(data);\r\n ");
bll.Append("}\r\n\r\n");
}
//删除
if (paramsData.CreateDeleteMethod)
{
bll.Append(" public bool " + paramsData.DeleteMethodName + "(" + ChangeToCSharpType(primaryKeyTypeName, false) + " " + parameterName + ")\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.DeleteMethodName + "(" + parameterName + ");\r\n ");
bll.Append("}\r\n\r\n");
}
//批量删除
if (paramsData.CreateBatchDeleteMethod)
{
bll.Append(" public bool " + paramsData.BatchDeleteMethodName + "(" + ChangeToCSharpType(primaryKeyTypeName, false) + "[] " + parameterName + ")\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.BatchDeleteMethodName + "(" + parameterName + ");\r\n ");
bll.Append("}\r\n\r\n");
}
//修改
if (paramsData.CreateUpdateMethod)
{
bll.Append(" public bool " + paramsData.UpdateMethodName + "(" + deletePrefixOfTableName + paramsData.ModelSuffix + " data)\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.UpdateMethodName + "(data);\r\n ");
bll.Append("}\r\n\r\n");
}
//查询
if (paramsData.CreateSelectMethod)
{
bll.Append(" public " + deletePrefixOfTableName + paramsData.ModelSuffix + " " + paramsData.SelectMethodName + "(" + ChangeToCSharpType(primaryKeyTypeName, false) + " " + parameterName + ")\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.SelectMethodName + "(" + parameterName + ");\r\n ");
bll.Append("}\r\n\r\n");
}
//查询所有
if (paramsData.CreateSelectAllMethod)
{
bll.Append(" public IList<" + deletePrefixOfTableName + paramsData.ModelSuffix + "> " + paramsData.SelectAllMethodName + "()\r\n ");
bll.Append("{\r\n ");
bll.Append("return dal." + paramsData.SelectAllMethodName + "();\r\n ");
bll.Append("}\r\n\r\n");
}
bll.Append(" }\r\n");
bll.Append("}");
return bll.ToString();
}
}

获取表所有外键sql

SELECT object_name(b.fkeyid) 外键表名称,(SELECT name FROM syscolumns WHERE colid = b.fkey AND id = b.fkeyid) 外键列名,
object_name(b.rkeyid) 主键表名,(SELECT name FROM syscolumns WHERE colid = b.rkey AND id = b.rkeyid) 主键列名
FROM sysobjects a JOIN sysforeignkeys b ON a.id = b.constid JOIN sysobjects c ON a.parent_obj = c.id
WHERE a.xtype = 'F' AND c.xtype = 'U'

源码有进行大量注释,考虑了可扩展性,如果新增其他数据库支持,很容易方便加入。如有好的建议,欢迎提出。

V1.3.3源码下载:http://pan.baidu.com/s/1c0pqOFY

更新日志:

2015-6-14:

1.修复生成查询所有数据方法时,BLL层调用错误-ok

2.不将SQL语句作为常量时,Insert方法前注释缩进有问题-ok

3.工厂类命名空间修改为从界面设置,默认使用Factory作为命名空间-ok

4.生成的DAL代码有错误,当表没有设置主键是自增列时,导致参数化sql的参数加上了[],如 where [ID]=[ID]

5.修复DAL和IDAL层生成查询所有数据方法名称错误问题

2015-7-8

1.生成简单三层时,Bll层using错误using IDAL修改为using DAL
using IDAL;
using Model;

2.修复注释不整齐问题

3.修改当表没有主键和自增列时,提示无法生成IDAL、DAL、BLL层问题

4.新增 DAL层新增一条数据方法的SQL语句不指定列名”功能和“生成实体类时,将表名和列名保存到常量字段加入”功能

2015-7-24

1.修复程序第一次打开时,生成代码层后的复选框没有按照选择的架构模式相应的禁用

2016-7-24

1.修复删除、更新、查询对组合主键的支持,之前版本只提取一个主键列。

2.修复批量删除方法对于字符串类型值的参数化,防止sql注入,之前版本直接拼接值。

3.修复数据库char对应C#char类型的转换,之前版本全部转换为string类型。

4.修复界面设置参数更改为空后,没有恢复到软件默认设置的值问题。

5.新增支持多个配置文件,不同的项目可以加载不同的配置文件。

分享最近抽空写的一个代码生成器,集成EasyDBUtility数据库访问帮助类的更多相关文章

  1. 【分享】自己写的一个可空的DateTimePicker控件-附源码

    最近这段时间在重构以前的一个项目,其中有一项就是要把DateTimePicker控件值可空.大家都知道的DateTimePicker值为DateTime类型,DateTime类型值不能等于Null.但 ...

  2. 分享一下自己写的一个vscode-leetcode答题插件

    0. 前言 春节这几天每天吃吃喝喝睡睡玩玩,突然发现明天就要上班了,吓得我虎躯一震. 春节结束之后,学生党们陆续开学,相信有许多同学马上就要在春季招聘中拼杀一番.想要收获心意的offer,当然免不了对 ...

  3. 分享下自己写的一个微信小程序请求远程数据加载到页面的代码

    1  思路整理 就是页面加载完毕的时候  请求远程接口,然后把数据赋值给页面的变量 ,然后列表循环 2 js相关代码  我是改的 onload函数 /** * 生命周期函数--监听页面加载 */ on ...

  4. 分享个刚写好的 android 的 ListView 动态加载类,功能全而代码少。

    (转载声明出处:http://www.cnblogs.com/linguanh/) 简介:      该ListView 实现动态加载数据,为了方便用户充分地自定义自己的数据源.点击事件,等核心操作, ...

  5. 自己写了一个解析json为table的工具类

    还需要完善的包括,css的封装,触发事件,数据的获得处理: <!DOCTYPE html> <html> <head> <meta charset=" ...

  6. 最近采集写的一个超简单实用的HTML解析类

    1. [文件] HtmlDom.php <?php$oldSetting = libxml_use_internal_errors( true ); libxml_clear_errors(); ...

  7. .netcore实现一个读写分离的数据库访问中间件

    在实际业务系统中,当单个数据库不能承载负载压力的时候,一般我们采用数据库读写分离的方式来分担数据库负载.主库承担写以及事务操作,从库承担读操作. 为了支持多种数据库我们先定义一个数据类型字典.key为 ...

  8. 一个C#的XML数据库访问类

    原文地址:http://hankjin.blog.163.com/blog/static/33731937200942915452244/ 程序中不可避免的要用到配置文件或数据,对于数据量比较小的程序 ...

  9. 实现用一个QueryService支持多数据库访问

    上图,是在服务端定义多个数据库,准备在客户端通过“联接名称”及“客户端服务名称”访问这些数据库. 基于实现的MultiDBQueryService,将其注册为一个指定客户端服务名称的服务,如下图: 这 ...

随机推荐

  1. addslashes,stripslashes

    官方介绍: (PHP 4, PHP 5) addslashes — 使用反斜线引用字符串 返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线.这些字符是单引号(’).双引号(”). ...

  2. asp.net 实现treeview 选中父节点其子节点也选种中 选中子节点其父节点与根节点也被选中

    1.在 Page_Load(object sender, EventArgs e) 里面加入: TreeView1.Attributes.Add("onclick", " ...

  3. 什么是LambdaExpression,如何转换成Func或Action(2)

    序言 在上一篇中,我们认识了什么是表达式树.什么是委托,以及它们的关系.可能是我功力不好,貌似大家都不怎么关注,没有讲解出不同角度的问题. 学习一种新技术,是枯燥的过程,只有在你掌握后并能运用时才能从 ...

  4. Vue 路由知识二(工程模式下路由的配置)

    vue-router是一个插件包,所以我们还是需要用npm/cnpm来进行安装的:npm/cnpm install vue-router --save-dev. 在路由的核心文件:src/router ...

  5. 观锁和乐观锁——《POJOs in Action》

    1        事务隔离 事务隔离是数据库提供的功能. SQL Server通过SET TRANSACTION ISOLATION LEVEL语句设置事务隔离级别: SET TRANSACTION ...

  6. PHP文件及目录考察点

    文件读取/写入操作 fopen()函数 用来打开一个文件,打开时需要指定打开模式 打开模式 模式 |作用 --- |--- 'r' |只读方式打开,将文件指针指向文件头. 'r+' |读写方式打开,将 ...

  7. 微信小程序中使用echarts

    一.效果图 二.代码 import * as echarts from '../../component/ec-canvas/echarts'; const app = getApp(); var x ...

  8. SqlServer数据库练习20190211

    一条update语句,修改多个条件 update orderdt_jimmy set qty = (case else qty end); 好了,就这样

  9. springboot Tomcat connector configured to listen on port 8081 failed to start.

    启动报 Tomcat connector configured to listen on port 8081 failed to start.   The port may already be in ...

  10. PHP Web开发入门流程

    在学习WEB开发前,至少有一个对C或者计算机编程任何一种语言的基本学习,这会对你以后的开发有一定的启蒙作用. 一.Web开发入门 推荐学习网址: http://www.w3school.com.cn/ ...