您的位置:首页 > 编程语言

ORM映射框架总结--代码生成器

2010-03-19 15:38 405 查看
年前发布了一些文章,是关于.NET数据操作(点击查看)的。刚开始学习编程的时候,总感觉Java中的Hibernate 功能好强大,现在也不可否认它的确强大,特别是它在数据关系处理上,却是那样的让人称叹。

当我那时还不知道.net 中的Linq的时候,一直想自己能够简单的写个ORM映射框架。去年花费了几个月的业务时间终于算是整出来了,一些基本操作都能够实现了,自己号称从数据库操作冗余代码中解脱出来,其实自己很天真,那个框架是多么的不完善。总结了一下,最近超体力透支的准备将其扩展,同时也碰到了一下很头疼的问题,那就是那个实体的生成。

每次都要去受到生成那些代码,是一件非常消耗体力的事情,而李老师的动软代码生成器也不能生成我想要的代码,于是自己查阅了一些资料,写了一个自己需要的代码生成器,在此共享一下。

1.效果图

看东西总是效果图比较直接,首先看看这个代码生成器的效果图。

代码 1 string servername = ddlServerName.SelectedItem.ToString();
2 string tableName = ddlTableNames.SelectedItem.ToString();
3 string connection = null;
4 SqlConnection con = null;
5 if (rbWindows.Checked)
6 {
7 connection = "server=" + servername + ";database=" + ddlDataBaseName.SelectedItem.ToString() + ";Integrated Security=true";
8 }
9 else
{
connection = "server=" + servername + ";database=master;uid=" + txtUserName.Text + ";pwd=" + txtPassword.Text;
}

try
{
con = new SqlConnection(connection);
con.Open();
StringBuilder sb = new StringBuilder("select ");
sb.Append("syscolumns.name as ColName ,");
sb.Append("systypes.name as ColTypeName ,");
sb.Append("syscolumns.length,");
sb.Append("sys.extended_properties.value as Mark ,");
sb.Append("IsAuto=case ");
sb.Append("when ( (SELECT COLUMNPROPERTY( OBJECT_ID('" + tableName + "'),'syscolumns.name','IsIdentity')) =1) ");
sb.Append("then 'true' else 'false' end,");
sb.Append("AllowNull=case ");
sb.Append("when (syscolumns.isnullable=0) then 'false' ");
sb.Append("else 'true' end,");
sb.Append("IsPK = Case ");
sb.Append(" when exists ( select 1 from sysobjects inner join sysindexes on sysindexes.name = sysobjects.name inner join sysindexkeys on sysindexes.id = sysindexkeys.id and sysindexes.indid = sysindexkeys.indid where xtype='PK' and parent_obj = syscolumns.id and sysindexkeys.colid = syscolumns.colid ) ");
sb.Append(" then 'true' else 'false' end ,");
sb.Append(" IsIdentity = Case syscolumns.status when 128 then 1 else 0 end from syscolumns inner join systypes on ( syscolumns.xtype = systypes.xtype and systypes.name <>'_default_' and systypes.name<>'sysname' ) left outer join sys.extended_properties on ( sys.extended_properties.major_id=syscolumns.id and minor_id=syscolumns.colid ) where syscolumns.id = (select id from sysobjects where name='"+tableName+"') ");
sb.Append(" order by syscolumns.colid");
SqlCommand command = new SqlCommand(sb.ToString(), con);
SqlDataReader reader = command.ExecuteReader();
ddlTableNames.Items.Clear();
StringBuilder sbCode = new StringBuilder("");
sbCode.Append("using System;\n");
sbCode.Append("using System.Collections.Generic;\n");
sbCode.Append("using System.Linq;\n");
sbCode.Append("using System.Text;\n");
sbCode.Append("using CommonData.Entity;\n");
sbCode.Append("using CommonData.Model.Core;\n");
sbCode.Append("\n");
sbCode.Append("namespace Entity\n");
sbCode.Append("{\n");

sbCode.AppendFormat("\t[Serializable]\n");
sbCode.AppendFormat("\t[TableAttribute(DBName = \"\", Name = \"{0}\", PrimaryKeyName = \"@PrimaryKeyName\", IsInternal = false)]\n", tableName);
sbCode.AppendFormat("\tpublic class {0}:BaseEntity\n", tableName.FirstToUpper(tableName));
sbCode.Append("\t{\n");
sbCode.AppendFormat("\t\tpublic {0}()\n", tableName.FirstToUpper(tableName));
sbCode.Append("\t\t{\n");
sbCode.Append("\t\t}\n\n");
string pkName="Id";
while (reader.Read())
{
if(reader["IsPK"].ToString()=="true")
{
pkName=reader["ColName"].ToString();
}
sbCode.AppendFormat("\t\tprivate {0} {1};\n", GetType(reader["ColTypeName"].ToString()), reader["ColName"].ToString().FirstToLower(reader["ColName"].ToString()));
sbCode.AppendFormat("\t\t[ColumnAttribute(Name = \"{0}\", IsPrimaryKey = {1}, AutoIncrement = {2}, DataType = DataType.{3}, CanNull = {4})]\n", reader["ColName"].ToString(), reader["IsPK"].ToString(), reader["IsAuto"].ToString(), GetDataType(reader["ColTypeName"].ToString()), reader["AllowNull"].ToString());
sbCode.AppendFormat("\t\tpublic {0} {1}\n", GetType(reader["ColTypeName"].ToString()), reader["ColName"].ToString().FirstToUpper(reader["ColName"].ToString()));
sbCode.Append("\t\t{\n");
sbCode.Append("\t\t\tget { return " + "".FirstToLower(reader["ColName"].ToString()) + "; }\n");
sbCode.Append("\t\t\tset { " + "".FirstToLower(reader["ColName"].ToString()) + " = value; }\n");
sbCode.Append("\t\t}\n\n");
}
sbCode.Append("\t}\n");
sbCode.Append("}\n");
sbCode.Replace("@PrimaryKeyName", pkName);
rtxtCode.Text = sbCode.ToString();
}
catch
{
MessageBox.Show("连接失败");
}
finally
{
if (con != null)
{
con.Close();
}
}

这段代码就是实现了上面实体的生成,这里已经没有多少东西了,只是一个拼字符串的工作。只要仔细认真就可以了。到此位置该介绍的东西就介绍完了。

当我做完这个东西的时候发现代码生成其核心并不是很难,掌握这些要点就能够写出一个实用的代码生成器。学习东西也是如此,掌握了核心,无论外形怎么变都是万变不离其宗。在后续的文章中将讲解个人框架了,相对于年前的那个来说这个ORM有了很大的改进,以后慢慢与大家分享自己的程序心得。

源码其实很简单,对于自动获取服务器名称这个功能还没有添加,还有那个自动附加数据库文件。这里上传一下源码,大家有兴趣看一下。 /Files/qingyuan/CodeCreate.zip
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: