前段时间用C#做网站,用到了大量数据库相关的东西。网站采用3层结构,即数据访问层(Data Access Layer),业务逻辑层(Business Logic Layer),页面表现层().做了一段时间,发现向数据访问层和业务逻辑层加入新的类,数据库的表结构改了,还要对应的修改数据访问层和业务逻辑层的代码,这个工作很是繁琐,无聊,而且容易出错。做了几次之后就想有什么办法可以让机器自动完成呢?

  联想到以前看过Java似乎有个Hibernate,可以很方便的实现对象关系映射(ORM),即自动的从数据库的表生成对应的对象,.Net也应该有类似的功能吧。于是找啊找,发现了很多.Net的ORM工具,不过都有缺点,就是代码得依赖于那些ORM工具,我希望能够让机器按我的要求生成我自己的代码,这样就更加灵活了。

  于是乎,发现了CodeSmith和MyGeneration,CodeSmith是 网上传的.NET 程序员十种必备工具之一,我们写代码时,经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。我们可以用CodeSmith编写模板自动完成这些任务,从而不仅提高工作效率,而且能够自动完成那些最为乏味的任务。可惜,CodeSmith是需要注册的,试用版只能用15天。而MyGeneration基本上和CodeSmith的功能差不多哦,但是他是开源的。我选软件的原则是能开源免费的就用,实在没替代了才选那些需要注册的,有版权的软件。所以就选MyGeneration了。

  用过一段时间后感觉MyGeneration主要是为了自动生成数据库相关的代码的,可能C#用得比较多,其实我们可以用它生成任何代码,C++,JavaScript...而且还不仅仅局限于数据库,其他方面的代码也可以用MyGeneration自动生成。比如我们经常用数据访问层和业务逻辑层,用MyGeneration就可以自动生成这些代码,我们可以不用手动写代码了。比如数据访问层,我们需要调用一个存储过程,用MyGeneration我们只需要选择生成存储过程代码的模板,执行一下脚本,然后在界面上选择数据库上某个存储过程,然后就自动生成了数据库访问代码,整个过程只需要点几下鼠标,代码就自动生成了。这对于需要大量操作数据库的程序员来说,效率是多大的提升啊。

废话少说,还是来点实在的吧。首先声明,我的MyGeneration版本是:1.3.0.3

安装完MyGeneration后,第一次启动会要求进行一些数据库相关的配置。如图:

ConnectionString: 就是指定连接哪个数据库了,填好这个就可以点确定了。

下面来看一看其他的项都是什么。

Language Mapping:就是指定数据库和对象基本类型的映射关系。让我们打开Languages.xml文件看一下吧:

     <Language From="SQL" To="C#">
<Type From="bigint" To="long" />
<Type From="binary" To="object" />
<Type From="bit" To="bool" />
<Type From="char" To="string" />
<Type From="datetime" To="DateTime" />
<Type From="decimal" To="decimal" />
<Type From="float" To="double" />
<Type From="image" To="byte[]" />
<Type From="int" To="int" />
<Type From="money" To="decimal" />
<Type From="nchar" To="string" />
<Type From="ntext" To="string" />
<Type From="numeric" To="decimal" />
<Type From="nvarchar" To="string" />
<Type From="real" To="float" />
<Type From="smalldatetime" To="DateTime" />
<Type From="smallint" To="short" />
<Type From="smallmoney" To="decimal" />
<Type From="text" To="string" />
<Type From="timestamp" To="byte[]" />
<Type From="tinyint" To="byte" />
<Type From="uniqueidentifier" To="Guid" />
<Type From="varbinary" To="byte[]" />
<Type From="varchar" To="string" />
<Type From="xml" To="string" />
<Type From="sql_variant" To="object" />
</Language>

这是里面的一段内容,很明显,是数据库SQL的字段转到C#是什么类型,里面没有C++的,假如我们要让它支持C++的话,需要在这里加入SQL到C++的类型转换。

Database Target Mapping:先看里面的内容吧:

     <DbTarget From="ACCESS" To="DAO">
<Type From="Text" To="DAO.dbText" />
<Type From="Memo" To="DAO.dbMemo" />
<Type From="DateTime" To="DAO.dbDate" />
<Type From="Currency" To="DAO.dbCurrency" />
<Type From="Yes/No" To="DAO.dbBoolean" />
<Type From="OLE Object" To="DAO.dbLongBinary" />
<Type From="Hyperlink" To="DAO.dbMemo" />
<Type From="Double" To="DAO.dbDouble" />
<Type From="Replication ID" To="DAO.dbGUID" />
<Type From="Long" To="DAO.dbLong" />
<Type From="Single" To="DAO.dbSingle" />
<Type From="Decimal" To="DAO.dbDecimal" />
<Type From="Byte" To="DAO.dbByte" />
<Type From="Integer" To="DAO.dbInteger" />
</DbTarget>

呵呵,一目了然,就是Access数据库用DAO的方式访问,数据库的列的类型对应的DAO里是什么类型。

UseMetaData目前没什么用。

看看MyGeneration的界面吧:

先让我们体验一下吧。

展开Template Browser面板下"d00dads - C#", 双击 “d00dads - Invoke a Stored Procedure", 让工作区显示其内容,

然后点击工具栏上的 "Execute" 按钮,如图红框所示:

弹出对话框,如图:

选择数据库,存储过程,存储过程类型,点确定(OK)。

然后可以看到工作区 Output 里输出了代码了。例如:

   using System.Data;
using System.Collections.Specialized;
using System.Data.SqlClient; public virtual void dm_exec_cursors (int spid)
{
ListDictionary parameters = new ListDictionary(); parameters.Add( new SqlParameter("@spid", SqlDbType.Int, ), spid);
LoadFromSqlNoExec("dm_exec_cursors", parameters);
}

这就是MyGeneration自动获取了存储过程的输入参数,然后在代码里构造相应的参数,然后生成的代码。

这只是MyGeneration自带的模板生成的,大家可以试一试其他的模板的效果。

里面有自动根据表结构生成BLL的类......看下效果:

 /*
'===============================================================================
' Generated From - CSharp_dOOdads_BusinessEntity.vbgen
'
' ** IMPORTANT **
' How to Generate your stored procedures:
'
' SQL = SQL_StoredProcs.vbgen
' ACCESS = Access_StoredProcs.vbgen
' ORACLE = Oracle_StoredProcs.vbgen
' FIREBIRD = FirebirdStoredProcs.vbgen
' POSTGRESQL = PostgreSQL_StoredProcs.vbgen
'
' The supporting base class OleDbEntity is in the Architecture directory in "dOOdads".
'
' This object is 'abstract' which means you need to inherit from it to be able
' to instantiate it. This is very easilly done. You can override properties and
' methods in your derived class, this allows you to regenerate this class at any
' time and not worry about overwriting custom code.
'
' NEVER EDIT THIS FILE.
'
' public class YourObject : _YourObject
' {
'
' }
'
'===============================================================================
*/
// Generated by MyGeneration Version # (1.3.0.3)
using System;
using System.Data;
using System.Data.OleDb;
using System.Collections;
using System.Collections.Specialized;
using MyGeneration.dOOdads;
namespace Your.Namespace
{
public abstract class _Users : OleDbEntity
{
public _Users()
{
this.QuerySource = "Users";
this.MappingName = "Users";
}
//=================================================================
// public Overrides void AddNew()
//=================================================================
//
//=================================================================
public override void AddNew()
{
base.AddNew(); } public override string GetAutoKeyColumn()
{
return "ID";
}
public override void FlushData()
{
this._whereClause = null;
this._aggregateClause = null;
base.FlushData();
} //=================================================================
// public Function LoadAll() As Boolean
//=================================================================
// Loads all of the records in the database, and sets the currentRow to the first row
//=================================================================
public bool LoadAll()
{
ListDictionary parameters = null; return base.LoadFromSql("[" + this.SchemaStoredProcedure + "proc_UsersLoadAll]", parameters);
} //=================================================================
// public Overridable Function LoadByPrimaryKey() As Boolean
//=================================================================
// Loads a single row of via the primary key
//=================================================================
public virtual bool LoadByPrimaryKey()
{
ListDictionary parameters = new ListDictionary(); return base.LoadFromSql("[" + this.SchemaStoredProcedure + "proc_UsersLoadByPrimaryKey]", parameters);
} #region Parameters
protected class Parameters
{ public static OleDbParameter ID
{
get
{
return new OleDbParameter("@ID", OleDbType.Integer, );
}
} public static OleDbParameter Alias
{
get
{
return new OleDbParameter("@Alias", OleDbType.VarChar, );
}
} }
#endregion #region ColumnNames
public class ColumnNames
{
public const string ID = "ID";
public const string Alias = "Alias";
static public string ToPropertyName(string columnName)
{
if(ht == null)
{
ht = new Hashtable(); ht[ID] = _Users.PropertyNames.ID;
ht[Alias] = _Users.PropertyNames.Alias;
}
return (string)ht[columnName];
}
static private Hashtable ht = null;
}
#endregion #region PropertyNames
public class PropertyNames
{
public const string ID = "ID";
public const string Alias = "Alias";
static public string ToColumnName(string propertyName)
{
if(ht == null)
{
ht = new Hashtable(); ht[ID] = _Users.ColumnNames.ID;
ht[Alias] = _Users.ColumnNames.Alias;
}
return (string)ht[propertyName];
}
static private Hashtable ht = null;
}
#endregion
#region StringPropertyNames
public class StringPropertyNames
{
public const string ID = "s_ID";
public const string Alias = "s_Alias";
}
#endregion #region Properties public virtual Integer ID
{
get
{
return base.GetInteger(ColumnNames.ID);
}
set
{
base.SetInteger(ColumnNames.ID, value);
}
}
public virtual String Alias
{
get
{
return base.GetString(ColumnNames.Alias);
}
set
{
base.SetString(ColumnNames.Alias, value);
}
}
#endregion #region String Properties public virtual string s_ID
{
get
{
return this.IsColumnNull(ColumnNames.ID) ? string.Empty : base.GetIntegerAsString(ColumnNames.ID);
}
set
{
if(string.Empty == value)
this.SetColumnNull(ColumnNames.ID);
else
this.ID = base.SetIntegerAsString(ColumnNames.ID, value);
}
}
public virtual string s_Alias
{
get
{
return this.IsColumnNull(ColumnNames.Alias) ? string.Empty : base.GetStringAsString(ColumnNames.Alias);
}
set
{
if(string.Empty == value)
this.SetColumnNull(ColumnNames.Alias);
else
this.Alias = base.SetStringAsString(ColumnNames.Alias, value);
}
}
#endregion private AggregateClause _aggregateClause = null;
#endregion protected override IDbCommand GetInsertCommand()
{ OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersInsert]"; CreateParameters(cmd); return cmd;
} protected override IDbCommand GetUpdateCommand()
{ OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersUpdate]"; CreateParameters(cmd); return cmd;
} protected override IDbCommand GetDeleteCommand()
{ OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersDelete]"; OleDbParameter p; return cmd;
} private IDbCommand CreateParameters(OleDbCommand cmd)
{
OleDbParameter p; p = cmd.Parameters.Add(Parameters.ID);
p.SourceColumn = ColumnNames.ID;
p.SourceVersion = DataRowVersion.Current;
p = cmd.Parameters.Add(Parameters.Alias);
p.SourceColumn = ColumnNames.Alias;
p.SourceVersion = DataRowVersion.Current;
return cmd;
}
}
}

这就是自动获得表结构,然后从字段映射成类里面的成员,并且还有一些插入,更新,删除的代码。

当然自带的模板生成的代码不一定符合我们的需要,但是我们可以根据需要自己写一些模板来生成符合自己需要的代码,这也是非常容易的事,欲知如何实现,请看下回文章。

本文转载自:http://blog.csdn.net/zxcred/article/details/2778193

代码自动生成工具MyGeneration之一的更多相关文章

  1. 代码自动生成工具MyGeneration之一(程序员必备工具)

    代码自动生成工具MyGeneration之一(程序员必备工具) 转 分类: C#2008-08-06 18:12 16064人阅读 评论(12) 收藏 举报 工具数据库相关数据库stringbrows ...

  2. 代码自动生成工具 MyGeneration

    MyGeneration 是一款不错的ORM和代码生成工具,它基于模板(Template)工作,安装好MyGeneration 后自带了很多模板,并且提供在线模板库提供模板升级和允许用户自定义模板.M ...

  3. Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展

    Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...

  4. 基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(v6.0.0版)

    TableGo v6.0.0 版震撼发布,此次版本更新如下: 1.UI界面大改版,组件大调整,提升界面功能的可扩展性. 2.新增BeautyEye主题,界面更加清新美观,也可以通过配置切换到原生Jav ...

  5. C# 代码自动生成工具

    开源:C# 代码自动生成工具,支持站点前后台   前言 写这个项目有很长一段时间了,期间也修修改改,写到最后,自己也没咋用(研究方向变化了). 正文 具体项目开源了:https://github.co ...

  6. iBatis 代码自动生成工具 iBator 及 Example 使用

    iBator的下载和安装 官方下载地址:http://people.apache.org/builds/ibatis/ibator/ 安装:见<Eclipse 插件安装> 安装完成后,“F ...

  7. 代码自动生成工具_java版

    项目结构: 这里要实现的功能是,当我们给出了bean,如:Admin,User,People等实体类后, 我想用代码自动生成我想要的代码,最后生成的效果: 也就是说为每一个bean都生成相应的Dao, ...

  8. mybatis-generator 代码自动生成工具

    今天来介绍下怎么用mybatis-gennerator插件自动生成mybatis所需要的dao.bean.mapper xml文件,这样我们可以节省一部分精力,把精力放在业务逻辑上. 之前看过很多文章 ...

  9. mybatis-generator 代码自动生成工具(maven方式)

    由于MyBatis属于一种半自动的ORM框架,所以主要的工作将是书写Mapping映射文件,但是由于手写映射文件很容易出错,mybatis-gennerator插件帮我们自动生成mybatis所需要的 ...

随机推荐

  1. Git----分支管理之解决冲突03

    人生不如意之事十之八九,合并分支往往也不是一帆风顺. 准备新的feature1分支,继续我们的新分支开发: $ git checkout -b feature1Switched to a new br ...

  2. Nagios自定义扩展

    原理:监控端通过check_nrpe把要监控的指令发送给被监控端,被监控端在本机执行监控任务,并把执行的结果发送回监控端. 如何扩展Nagios,以实现自定义监控? 借助插件进行的每一次有效的Nagi ...

  3. UGUI RectTransform

    RectTransform解析 当 Anchor 在同一点时,显示的是物体的座标与大小Pos X.Pos Y.Width.Height ,当 Anchor 不在同一点时(此时会形成矩形),显示的会是 ...

  4. vim跳转到指定行

    第一种方法 在编辑模式下(非输入模式)下输入ngg 或者 nGn为指定的行数(如25)25gg或者25G 跳转到第25行. 25gg 第二种方法 在命令模式下输入行号n : n 查看当然光标所在的行和 ...

  5. node系列:全局与本地

    查看:默认和当前的 全局与本地 全局路径:npm config get prefix 本地路径:npm config get cache 修改 修改就会创建对应目录(文件夹) 修改本地路径:npm c ...

  6. 用js来实现银行家算法

    Number.prototype.round = function (len) { var old = this; var a1 = Math.pow(10, len) * old; a1 = Mat ...

  7. es进行curl请求时报错:missing authentication token for REST request

    把host 修改一下即可 ELASTICSEARCH_HOST=http://user:password@URL:port

  8. lrzsz的安装与配置

    1)下载http://freshmeat.sourceforge.net/projects/lrzsz/ 2)tar zxvf lrzsz-0.12.20.tar.gz 3)mv lrzsz-0.12 ...

  9. Process ProcessThread Thread

    Process ProcessThread: Process and ProcessThread objects have a ProcessorAffinity property of IntPtr ...

  10. 调试PHP如何让浏览器提示错误

    php.ini中的display_errors的值改为On:或者php代码页顶部加上ini_set("display_errors", "On"); error ...