文档章节

简单代码生成器原理剖析(二)

 木宛城主
发布于 2015/03/02 19:42
字数 974
阅读 10
收藏 0

上篇《简单代码生成器原理剖析(一)》分析了代码生成器的原理,查询数据库系统视图:INFORMATION_SCHEMA.TABLES、 INFORMATION_SCHEMA.COLUMNS  可以获得数据库中表、列的相关信息,再运用StringBuilder类的其AppendLine方法追加字符串,最后早运用File.WriteAllText方法将字符串写入文件。

第二版代码生成器在第一版的基础上扩展了以下功能:

  • 使用了部分类(partial):当使用大项目或自动生成的代码(如由 Windows 窗体设计器提供的代码)时,将一个类、结构或接口类型拆分到多个文件中的做法就很有用。 分部类型可能包含分部方法。
  •  使用可空类型:由于数据库中表中数据很有可能是NULL,可空类型使得数据从表中读取出来赋值给值类型更加兼容。
  • 增加了ToModel方法:将数据库表中一行数据封装成Model类的对象返回。
 
Model的实现:
/// <summary>
/// Model
/// </summary>
public static void CreateModel(CodeBuilderArgs args,string tableName)
{
DataTable dt = ExecuteDataTable(args.ConnectionString, "select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@TABLE_NAME"
,new SqlParameter("TABLE_NAME",tableName));
StringBuilder sb = new StringBuilder();
sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using System.Linq;");
sb.AppendLine("using System.Text;");
sb.AppendLine("namespace " + args .Namespace+ ".Model");
sb.AppendLine("{");
sb.AppendLine("partial class " + tableName);
sb.AppendLine("{");
foreach (DataRow row in dt.Rows)
{
string colName = Convert.ToString(row["COLUMN_NAME"]);
string colType = Convert.ToString(row["DATA_TYPE"]);

Type netType = GetTypeByDBType(colType);
string netTypeName;
if (netType.IsValueType)
{
netTypeName = netType + "?";
}
else
{
netTypeName = netType.ToString();
}
sb.AppendLine("public " +netTypeName +" "+ colName + " { get; set; }");
}
sb.AppendLine(" }");
sb.AppendLine(" }");
string modelDir = Path.Combine(args.OutputDir, "Model");
string modelFile = Path.Combine(modelDir, tableName+".cs");
Directory.CreateDirectory(modelDir);
File.WriteAllText(modelFile, sb.ToString());
}
DAL(数据访问层)的实现:
 
/// <summary>
///DAL
/// </summary>
/// <param name="args"></param>
/// <param name="tableName"></param>
public static void CreateDAL(CodeBuilderArgs args, string tableName)
{
StringBuilder sb = new StringBuilder();
DataTable dt = ExecuteDataTable(args.ConnectionString, "select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@TABLE_NAME"
, new SqlParameter("TABLE_NAME", tableName));
sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using System.Linq;");
sb.AppendLine("using System.Text;");
sb.AppendLine("using "+args.Namespace+".Model;");
sb.AppendLine("using System.Data.SqlClient;");
sb.AppendLine("using System.Data;");
sb.AppendLine("namespace "+args.Namespace+".DAL");
sb.AppendLine("{");
sb.AppendLine("partial class "+tableName+"DAL");
sb.AppendLine("{");
sb.AppendLine("public int AddNew("+tableName+" model)");
sb.AppendLine("{");

string[] cols = GetColsWithoutId(GetCols(dt, new List<string>())).ToArray();
var colsParameters=from e in cols select"@"+ e;
sb.AppendLine("string sql = \"insert into " + tableName + "(" + string.Join(",", cols) + ") output inserted.id values(" + string.Join(",", colsParameters.ToArray()) + ")\";");
sb.AppendLine("int id = (int)SqlHelper.ExecuteScalar(sql");

foreach (DataRow row in dt.Rows)
{
string colName = Convert.ToString(row["COLUMN_NAME"]);
if(!(colName.ToLower()=="id"))
{
sb.AppendLine(", new SqlParameter(\""+colName+"\", model."+colName+")");
}

}
sb.AppendLine(");");
sb.AppendLine("return id;");
sb.AppendLine("}");

var par=from e in cols select e+"="+"@"+e;
sb.AppendLine("public bool Update("+tableName+" model)");
sb.AppendLine("{");
sb.AppendLine("string sql = \"update "+tableName+" set "+string.Join(",",par.ToArray())+" where id=@id\";");
sb.AppendLine("int rows = SqlHelper.ExecuteNonQuery(sql");
foreach (DataRow row in dt.Rows)
{
string colName = Convert.ToString(row["COLUMN_NAME"]);
sb.AppendLine(", new SqlParameter(\"" + colName + "\", model." + colName + ")");
}
sb.AppendLine(");");
sb.AppendLine("return rows>0;");
sb.AppendLine("}");


sb.AppendLine("public bool Delete(int id)");
sb.AppendLine("{");
sb.AppendLine("int rows = SqlHelper.ExecuteNonQuery(\"delete from "+tableName+" where id=@id\",");
sb.AppendLine("new SqlParameter(\"id\", id));");
sb.AppendLine("return rows > 0;");
sb.AppendLine("}");

sb.AppendLine("private static "+tableName+" ToModel(DataRow row)");
sb.AppendLine("{");
sb.AppendLine(""+tableName+" model = new "+tableName+"();");
foreach (DataRow row in dt.Rows)
{
string colName = Convert.ToString(row["COLUMN_NAME"]);
string colType = Convert.ToString(row["DATA_TYPE"]);

Type netType = GetTypeByDBType(colType);
string netTypeName;
if (netType.IsValueType)
{
netTypeName = netType + "?";
}
else
{
netTypeName = netType.ToString();
}
sb.AppendLine("model."+colName+" = row.IsNull(\""+colName+"\") ? null : "+"("+netTypeName+")"+"row[\""+colName+"\"];");
}
sb.AppendLine("return model;");
sb.AppendLine("}");



//
sb.AppendLine("public "+tableName+" Get(int id)");
sb.AppendLine("{");
sb.AppendLine("DataTable dt = SqlHelper.ExecuteDataTable(\"select * from "+tableName+" where id=@id\",");
sb.AppendLine("new SqlParameter(\"id\", id));");
sb.AppendLine("if(dt.Rows.Count > 1)");
sb.AppendLine("{");
sb.AppendLine("throw new Exception(\"more than 1 row was found\");");
sb.AppendLine("}");
sb.AppendLine("if(dt.Rows.Count <= 0)");
sb.AppendLine("{");
sb.AppendLine("return null; ");
sb.AppendLine("}");
sb.AppendLine("DataRow row = dt.Rows[0];");
sb.AppendLine(""+tableName+" model = ToModel(row);");
sb.AppendLine("return model;");
sb.AppendLine("}");

sb.AppendLine("public IEnumerable<"+tableName+">ListAll()");
sb.AppendLine("{");
sb.AppendLine("List<"+tableName+"> list = new List<"+tableName+">();");
sb.AppendLine("DataTable dt = SqlHelper.ExecuteDataTable(\"select * from "+tableName+"\");");
sb.AppendLine("foreach (DataRow row in dt.Rows)");
sb.AppendLine("{");
sb.AppendLine("list.Add(ToModel(row));");
sb.AppendLine("}");
sb.AppendLine("return list;");
sb.AppendLine("}");
sb.AppendLine("}");
sb.AppendLine("}");

string DALlDir = Path.Combine(args.OutputDir,"DAL");
string DALFile = Path.Combine(DALlDir,tableName+"DAL.cs");
Directory.CreateDirectory(DALlDir);
File.WriteAllText(DALFile,sb.ToString());
}
private static IEnumerable<string> GetColsWithoutId(List<string> cols)
{
var colArray = from col in cols where col.ToLower() != "id" select col;
return colArray;
}
private static List<string> GetCols(DataTable dt, List<string> cols)
{
foreach (DataRow row in dt.Rows)
{
string colName = Convert.ToString(row["COLUMN_NAME"]);
cols.Add(colName);
}
return cols;
}
BLL的实现:
/// <summary>
/// BLL
/// </summary>
/// <param name="args"></param>
/// <param name="tableName"></param>
public static void CreateBLL(CodeBuilderArgs args,string tableName)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using System.Linq;");
sb.AppendLine("using System.Text;");
sb.AppendLine("using "+args.Namespace+".Model;");
sb.AppendLine("using "+args.Namespace+".DAL;");
sb.AppendLine("namespace "+args.Namespace+".BLL");
sb.AppendLine("{");
sb.AppendLine("partial class "+tableName+"BLL");
sb.AppendLine("{");
sb.AppendLine("public int AddNew("+tableName+" model)");
sb.AppendLine("{");
sb.AppendLine("return new "+tableName+"DAL().AddNew(model);");
sb.AppendLine("}");
sb.AppendLine("public bool Delete(int id)");
sb.AppendLine("{");
sb.AppendLine("return new "+tableName+"DAL().Delete(id);");
sb.AppendLine("}");
sb.AppendLine("public bool Update("+tableName+" model)");
sb.AppendLine("{");
sb.AppendLine("return new "+tableName+"DAL().Update(model);");
sb.AppendLine("}");
sb.AppendLine("public "+tableName+" Get(int id)");
sb.AppendLine("{");
sb.AppendLine("return new "+tableName+"DAL().Get(id);");
sb.AppendLine("}");
sb.AppendLine("public IEnumerable<"+tableName+"> ListAll()");
sb.AppendLine("{");
sb.AppendLine("return new "+tableName+"DAL().ListAll();");
sb.AppendLine("}");
sb.AppendLine("}");
sb.AppendLine("}");
string BLLDir = Path.Combine(args.OutputDir,"BLL");
string BLLFile = Path.Combine(BLLDir,tableName+"BLL.cs");
Directory.CreateDirectory(BLLDir);
File.WriteAllText(BLLFile,sb.ToString());
}
详细代码可参考:

© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 222
码字总数 199010
作品 0
黄浦
如何基于yeoman快速编写脚手架工具(系列:使用篇上)

如何基于yeoman快速编写脚手架工具(系列:使用篇上) 由于关于yeoman编写脚手架的文章太少,所以推出此文,注意本文介绍的yoeman generator-generator是基于 0.8.0以前的版本,0.1.0以后的版...

刘学炜
2016/01/23
515
0
TensorFlow实现seq2seq

前言 前面在《深度学习的seq2seq模型》文章中已经介绍了seq2seq结构及其原理,接下去这篇文章将尝试使用TensorFlow来实现一个seq2seq网络结构,该例子能通过训练给定的训练集实现输入某个序列...

sea-boat
2017/09/14
0
0
Python中的yield

一、迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对...

翼动动空
2016/05/09
765
0
Mybatis-plus 1.2.2 发布,MyBatis 增强工具包

mybatis-plus 1.2.2 发布了。MyBatis 增强工具包,简化 CURD 操作。 启动加载 XML 配置时注入单表 SQL 操作 ,为简化开发工作、提高生产率而生。 mybatis-plus 实践及架构原理 与其他工具包区...

青苗
2016/03/14
8.3K
9
Javac编译原理:Item(1)——基本介绍

首先,必须明确Java语言规范和Java虚拟机规范不是一回事。 Java语言规范描述了Java语言有哪些词法和语法,而Java虚拟机也有Java虚拟机规范,它们都有自己的词法和语法解析规则,而且解析规则...

_Roger_
2016/02/16
135
0

没有更多内容

加载失败,请刷新页面

加载更多

Win10内部更新:警告用户别用chrome和Firefox

简评:别和 Chrome 和 Firefox 约行不,我 Edge 明明更美、屁股更翘、更性感。。。 微软正在测试 Windows 10 的一个更新:警告用户不要安装 Chrome 和 Firefox。是测试人员发现的这个新警告,...

极光推送
30分钟前
2
0
Java并发编程高阶技术 高性能并发框架源码解析与实战

全网唯一深度解析并发编程框架disruptor底层源码课程,助你成为并发编程高手,拿下高薪 网盘地址下载

qq__2304636824
今天
1
0
day92-20180918-英语流利阅读-待学习

健身最大的敌人不是懒惰,而是逞强 Daniel 2018-09-19 1.今日导读 还记得 2008 年北京奥运会运动员刘翔的退赛风波吗?那天几乎所有中国人都将视线聚焦在了鸟巢体育馆 110 米栏的项目上,迫不...

飞鱼说编程
今天
8
0
70.shell的函数 数组 告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析 20.16/20.17 shell中的函数: ~1. 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段...

王鑫linux
今天
3
0
分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部