开篇
本篇主要介绍如何使用现有的技术而不是使用AgileEAS.NET应用开发平台自带的ORM设计器,而是我们实现自己的代码生成器一步一步的。希望大家能在学习的
过程中对代码生成器本身有个更深入的认识与了解,本人技术水平有限,本篇只是抛砖引玉,错误之处,还请大家批评支出。
序言
代码生成器主要的目的,是适应我们自己的已有框架的编码格式,生成我们需要的基础代码。虽然目前开源的代码生成器也比较多,但是有时候我们自己已有一个
比较成熟的,易用的,快速的稳定的开发框架,这时候写个自定义的代码生成器就极其必要。代码生成器的主要目标是根据数据库表结构生成实体层与数据层代码,当
然具体的业务代码可能还要自己手动来做,代码生成器只能生成基本的增删修查的业务代码。
开始构建
一般情况下我们的代码生成器首先需要与数据库进行关联,或者是从自定义格式文件中动态的读取实体信息。我们从简单的开始吧。我们本篇都已数据库的链接为
例构建简单的代码代码生成器。首先需要一个简单的数据库链接的配置页面,配置文件可以直接通过XML文件来存储,或者不构建这样的可视化的配置界面,直接通过
XML文件来实现。
由于本篇意在指导大家来做,所以这里就直接通过XML来配置数据库访问字符串。
<?xml version="1.0" encoding="utf-8" ?>
<Connection>
<ConnectionItem name="ConnectionString" type="SQLServer">Data Source=.\SQLEXPRESS;Initial Catalog=EasyStore;User ID=es;Password=123456</ConnectionItem>
<ConnectionItem name="ConnectionString1" type="Oracle"></ConnectionItem>
<ConnectionItem name="ConnectionString2" type="Access"></ConnectionItem>
</Connection>
首先是根据XML配置文件中读取链接字符串,读取ConnectionString,然后与数据建立链接。
主要代码如下:
该类负责读取XML文档中节点的值
public class ConfigXml
{
public static ConfigXml instance;
public static ConfigXml Instance
{
get
{
if (instance == null)
instance = new ConfigXml();
return instance;
}
}
public string GetConnectionString(string filename, string type)
{
string value = string.Empty;
string path = System.IO.Directory.GetCurrentDirectory().Replace("\\bin", "") + "/CommonLibary/" + filename + ".xml";
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("ConnectionItem");
foreach (XmlNode node in nodes)
{
XmlElement ele = (XmlElement)node;
if (ele.GetAttribute("type") == type)
{
value = ele.InnerText;
}
}
return value;
}
}
通过这个类文件就可以读取出链接字符串,接下来就是在具体生成代码的主界面中通过这个类提供的方法,从数据库中读取出所有的该数据库下的所有的表,绑定在树形列表中:
private string connectionString = @"" + ConfigXml.Instance.GetConnectionString("ConfigXmlPath", "SQLServer") + "";
public OfficeWordCreator()
{
InitializeComponent();
this.InitInfo();
}
private void InitInfo()
{
SqlAccess sql = new SqlAccess();
string sqlText = " SELECT A.NAME,B.NAME OWNER FROM SYSOBJECTS A LEFT JOIN SYSUSERS B ON A.UID = B.UID WHERE A.TYPE = 'U' AND A.NAME<>'dtproperties' ORDER BY A.NAME";
sql.ConnectionString = this.connectionString;
this.InitTreeList(sql.Query(sqlText));
}
private void InitTreeList(DataTable dataTable)
{
TreeNode root = new TreeNode("数据库表", 0, 1);
foreach (System.Data.DataRow row in dataTable.Rows)
{
TreeNode node = new TreeNode(row["name"].ToString(), 2, 3);
node.Tag = row["name"].ToString();
root.Nodes.Add(node);
}
this.tvwList.Nodes.Add(root);
this.tvwList.ExpandAll();
}
绑定后的效果如图:
接下来我们的操作可能是选择树形的节点后,自动在右侧显示该表中的数据字段。
private void tvwList_AfterSelect(object sender, TreeViewEventArgs e)
{
if (this.tvwList.SelectedNode == null)
return;
if (this.tvwList.SelectedNode.Tag == null)
return;
this.tbDbName.Text = this.tvwList.SelectedNode.Tag.ToString();
StringBuilder sb = new StringBuilder();
sb.Append(" SELECT ");
sb.Append("A.NAME,A.COLID,C.NAME TYPE,A.LENGTH BYTES,COLUMNPROPERTY(A.id,A.name,'precision') LENGTH,");
sb.Append("A.XPREC [PRECISION],ISNULL(COLUMNPROPERTY(A.ID,A.NAME,'Scale'),0) SCALE,ISNULL(D.TEXT,'') DEFAULTVALUE,");
sb.Append("CASE when exists(SELECT 1 FROM SYSOBJECTS where xtype='PK'and name in ( SELECT NAME FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid ))) then '1' else '0' END PK,");
sb.Append("F.NAME TABLE_NAME,F.OWNER TABLE_OWNER ");
sb.Append("FROM SYSCOLUMNS A LEFT JOIN SYSOBJECTS B ON A.ID = B.ID ");
sb.Append("LEFT JOIN SYSTYPES C ON A.XTYPE=C.XUSERTYPE ");
sb.Append("LEFT JOIN SYSCOMMENTS D ON A.CDEFAULT = D.ID ");
sb.Append("INNER JOIN ");
sb.Append("(SELECT A.NAME,A.ID,B.NAME OWNER FROM SYSOBJECTS A LEFT JOIN SYSUSERS B ON A.UID = B.UID WHERE A.TYPE = 'U' OR A.TYPE = 'V') F ON A.ID = F.ID ");
sb.Append(" AND F.NAME='" + this.tbDbName.Text + "' ORDER BY A.COLID");
string sqlText = sb.ToString();
SqlAccess access = new SqlAccess();
access.ConnectionString = this.connectionString;
this.InitlvwInfo(access.Query(sqlText));
}
private void InitlvwInfo(DataTable dataTable)
{
this.lvwInfo.Items.Clear();
this.lvwInfo.BeginUpdate();
foreach (System.Data.DataRow row in dataTable.Rows)
{
ListViewItem item = new ListViewItem(new string[] { "", row["name"].ToString(), row["type"].ToString(), row["bytes"].ToString(), row["PK"].ToString() == "1" ? "是" : "否" });
item.Tag = row;
this.lvwInfo.Items.Add(item);
}
this.lvwInfo.Tag = dataTable;
this.lvwInfo.EndUpdate();
}
通过上面的2个函数即可实现,当选中某个属性节点后,列表中自动显示该表下的所有的列。具体效果如图:
然后通过选中的字段名称,点击生成文档,然后在不同的文档页面中就生成了不同的代码。
当然可能生成的代码还有部分错误,这里只是抛砖引玉。为不熟悉这块内容的朋友提供一个简单的认识。
源码下载
如果各位有好的建议还请多多给我提出改进意见。谢谢您的意见。
作者:IT行者-何戈洲
出处:http://www.cnblogs.com/hegezhou_hot/
2007年大学毕业后便投入到计算机行业中,先后涉足(电信、电子商务、教育、医疗、工程建筑、项目管理、房产)等行业,目前有比较丰富的技术及行业经验,技术方面涉及(Java、Go、.NET、Python、设计模式、系统架构、PM管理流程、软件工程、敏捷开发、SOA、云计算、大数据、区块链、WF、SAAS等领域),结合业务可提供(EIP、ERP、HIS、B2B、B2C、B2B2C、CRM、OA、O2O等)业务及技术解决方案,随着时间的推移,目前已逐步转向管理方面,欢迎同行一起交流学习,个人平时爱好体育运动、音乐、旅游等,向往丰富多彩的生活旅程。如有问题或建议,请多多赐教!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过hegezhou_hot@163.com 联系我,非常感谢。
其他联系方式:
电话:13716055594
联系人:何戈洲
微信联系我: