避免重复劳动-C# 实体类生成工具下载(WPF)

小软开发手记 (请移步 http://www.cnblogs.com/flashbar/archive/2012/01/04/MyGenerator.html 获取最新版本)

先讲讲开发目的:为了不再很机械的复制粘贴复制再粘贴,往返于VS和SQL中间,于是上网找有没有自动生成实体类的东西。找了一圈,发现有是有,不过都不是自己需要的,有的功能太强,有的界面不够简洁,其实我要求的功能挺少挺简单的,但是就是找不到,很郁闷~ 于是决定自己花点时间写一个。

  刚开始的目的仅限于此,后面慢慢说开发过程,遇到的问题和解决方案,希望这个软件可以给大家带来方便,开发过程中的一些经验也对大家有帮助。

第一天

我做的事情:

1. 软件的架构工作,汇报如下:

软件需求:(1)根据用户输入的DB Server的信息(IP,User,Password)自动获取Server上的DB列表(有改进)

     (2)根据用户选择的DB,读出所有的Table和对应Table上的所有字段,做成List (有改进)

     (3)根据用户单击的的Table自动生成该Table的实体类(有改进)

开发环境和语言: VS2010, C#, WPF

2. MainWindow的Layout设计和Coding

这部分为需求(1),刚开始想的简单,拖几个TextBox然后让用户输入一些信息,然后再把得到的数据库绑定到一个Combobox就算OK。于是开始做界面。

这部分的主要代码如下:

读取所有数据库
string connStr ="";
if (ChkIsWindows.IsChecked !=true)
{
connStr
=string.Format(
"Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}",
dataSource, inCa, uid, pwd);
}
else
{
connStr
=string.Format(
"Data Source={0};Initial Catalog={1};Trusted_Connection=SSPI", dataSource,"Master");
}
_sqlstr
="Select Name From Master..sysdatabases";
return SqlUtility.GetDataTableBySqlStr(connStr, _sqlstr, out errMsg);

如上,第一个分支判断是否为使用系统验证的,两种登入SQL Server的方式,连接字符串是不同的。

做完了后的界面如下:

怎么样? 还比较清爽吧? 选中第一个复选框会自动带出DB Server 和 Login ID, Password也不用填了。

第二天

我做的事情:

1. 主窗口,用作自动生成代码的界面设计

2. 需求(2)的功能实现和软件性能优化,如何能快速的读出远程

这部分是主要部分,良好的用户体验是必不可少的,开始的想法太简单,并且不易用,因为肯定有很多人想一次生成很多Table的实体,或者只想为部分字段做属性。

于是我决定使用TreeView空间,Table作为主节点,字段作为子节点。然后在每个节点处加入CheckBox用来限制选定与否。这些都是在程序中控制的。

3. 初始化一个Tab用来放置文本模板,这样用户就可以自定义文本生成模板了,使用范围就更广了(今天刚发现,这个用来把读取的DataSet中的Column数据都赋值到对应的实体中也是很方便的)

主要代码如下:

初始化TreeView
#region Init TreeView
privatevoid InitDtList()
{
string errMsg;
DataTable tbList
= GetTbList(out errMsg);
if (!string.IsNullOrEmpty(errMsg))
{
TxtNote.Text
= errMsg;
return;
}
if (tbList !=null&& tbList.Rows.Count >0)
{
TrvTbList.Items.Clear();
for (int i =0; i < tbList.Rows.Count; i++)
{
CheckBox cb
=new CheckBox
{
Content
= tbList.Rows[i][0].ToString(),
Tag
= i
};
cb.Click
+= CbTable_Click;

TreeViewItem tvItem
=new TreeViewItem
{
Header
= cb,
};
TrvTbList.Items.Add(tvItem);
InitColumnList(tvItem, tbList.Rows[i][
0].ToString());
}
}
else
{
TxtNote.Text
=string.Format("No Table in DataBase: {0}", Program.SelectedDb);
}
}
privatevoid InitColumnList(TreeViewItem tvItemHeader, string dtName)
{
string errMsg;
DataTable columnList
= GetColumnList(dtName, out errMsg);
if (!string.IsNullOrEmpty(errMsg))
{
TxtNote.Text
= errMsg;
return;
}
if (columnList !=null&& columnList.Rows.Count >0)
{
tvItemHeader.Items.Clear();
for (int i =0; i < columnList.Rows.Count; i++)
{
string[] types = Program.GetTypeById(columnList.Rows[i][1].ToString());
CheckBox subCb
=new CheckBox
{
Content
=string.Format("{0} (SQL: {1})", columnList.Rows[i][0], types[0]),
Tag
= types,
ToolTip
= columnList.Rows[i][0]
};
TreeViewItem tvSubItem
=new TreeViewItem
{
Header
= subCb,
ToolTip
="C#: "+ types[1]
};
tvItemHeader.Items.Add(tvSubItem);
}
}
}
private DataTable GetTbList(outstring errMsg)
{
_sqlstr
="Select Name From SysObjects Where XType='U' order By Name";
return SqlUtility.GetDataTableBySqlStr(Program.Connstr, _sqlstr, out errMsg);
}
private DataTable GetColumnList(string dtName, outstring errMsg)
{
_sqlstr
=
string.Format(
@"select sc.name as Name,sc.xtype as Type from syscolumns sc,sysobjects so
where sc.id = so.id and so.name = N'{0}'
", dtName);
return SqlUtility.GetDataTableBySqlStr(Program.Connstr, _sqlstr, out errMsg);
}

然后就是根据用户的选择自动生成代码了,这里我用了TabControl空间,然后动态添加TabItem。代码如下:

添加Tab
#region Add Tabs
privatevoid AddEntityTabsByTreeView(TreeView tv)
{
string tempStr = ((TextBox)tabItem0.Content).Text;
foreach (var item in tv.Items)
{
string entityStr ="";
CheckBox cb
= ((TreeViewItem)item).Header as CheckBox;
if (cb !=null&& cb.IsChecked ==true)
{
foreach (var subItem in ((TreeViewItem)item).Items)
{
CheckBox subCb
= ((TreeViewItem)subItem).Header as CheckBox;
if (subCb !=null&& subCb.IsChecked ==true&&!string.IsNullOrEmpty(tempStr))
{
entityStr
+= tempStr.Replace("%ColummName%", subCb.ToolTip.ToString()).Replace("%ColummType%",
((
string[])subCb.Tag)[
1]) +"\n";
}
}
if (!string.IsNullOrEmpty(entityStr))
{
TabItem tabItem
=new TabItem { Header = cb.Content };
TextBox tb
=new TextBox { Text = entityStr };
tb.TextWrapping
= TextWrapping.Wrap;
tb.AcceptsReturn
=true;
tb.VerticalScrollBarVisibility
= ScrollBarVisibility.Visible;
tabItem.Content
= tb;
TabEntity.Items.Add(tabItem);
}
}
}
}
#endregion


做完了后的界面如下:

注意,这里我是使用一个xml文件来做类型映射的,第二天完工...

第三天

我做的事情:

1. 加入了一些常用功能,比如后退,退出,重置,当前Tab的文本Copy等等

2. 页面控件的重新布局

3. 加入了错误信息的提示

4. 重头戏,程序代码的优化,使用了少少的全局变量,从而大量减少了远程连接时的超时现象

得到SQL中和.Net中的对应数据类型
publicstaticstring[] GetTypeById(string typeId)
{
if (TypeDic ==null||!TypeDic.ContainsKey(typeId))
{
string mapFile ="TypeMap.xml";
DataSet ds
=new DataSet();
ds.ReadXml(mapFile);
if (ds.Tables["type"] ==null&& ds.Tables["type"].Rows.Count <=0)
{
returnnull;
}
TypeDic
=new Dictionary<string, string[]>();
for (int i =0; i < ds.Tables["type"].Rows.Count; i++)
{
string[] dataTypes =newstring[2];
dataTypes[
0] = ds.Tables["type"].Rows[i][0].ToString();
dataTypes[
1] = ds.Tables["type"].Rows[i][2].ToString();
if (!TypeDic.ContainsKey(ds.Tables["type"].Rows[i][1].ToString()))
{
TypeDic.Add(ds.Tables[
"type"].Rows[i][1].ToString(), dataTypes);
}
}
}
return TypeDic[typeId];
}

5. 使用Config文件,便于用户的配置

好了,完工了,就说到这,希望对大家有用。

基本功能:
        1. 根据需要自动生成实体类
        2. 自动生成存储过程,包含每个表(Table)的基本SQL查询语句
        3. 自动生成WEB层前后端相关代码
        4. 自动生成BLL层的几个基本业务操作的代码
        5. 数据库操作支持T-SQL事务,设置简单
        6. 支持模板自定义,生成你想要的代码片段
        7. 单文件绿软,便于携带

运行环境:
        1. Win XP/2003/2008/Vista/Win7
        2. .Net Framework 3.0/3.5/4.0

更新历史:

   最后更新日期: 2011/12/20
        V3.2.0.0
        修改:BLL层代码根据Table自动生成,更加符合面向对象的原则
        修改:WEB前端方法调用更加简单
        修改:修复已知的几个代码生成错误的问题
        修改:Web后台代码调整,更加通用
   V3.1.0.0
        增加:代码生成时对非主键自增字段的处理逻辑
        增加:增加对中文字段和中文数据库名的支持
        修改:存储过程中用中括号括起字段名,避免冲突
        修改:存储过程中增加唯一性确定过程,后端代码在插入和更新的过程中加入唯一性判断的事务
        修改:说明性文字部分修改和修正
        V3.0.0.0
        增加:界面布局调整,更加符合用户体验
        增加:界面切换效果
        修改:取消BLL和DAL层得代码自动生成,改为通用类,无需根据数据表生成
        修改:大幅修改代码生成,支持使用多数据库操作的T-SQL事务,整个数据库访问流程更加灵活,支持数据库操作的智能提示
        修改:修复已知的几个代码生成错误的问题
        V2.1.0.0
        增加:全面支持SQL Server 2008 R2
        修改:修复两个已知会造成程序退出的Bug
        V2.0.0.0
        增加:BLL,DAL,WEB层的自动代码生成
        增加:“关于”和“帮助”页面
        修改:软件正式更名为 我的代码生成器(My Generator)
        修改:布局调整
        V1.8.0.0
        优化:一些用户体验的调整,切换功能自动生成对应代码,字段列表选择更加符合用户体验
        修改:修复一个生成的代码中,如果有DateTime类型,那么默认空值存入数据库可能会溢出的错误
        修改:增加某些字段类型的精度显示
        修改:登录窗口的服务器和数据库名支持手动输入
        修改:布局调整,增加反选按钮
        V1.7.0.0
        增加:DB Server的别名功能,可以为同一个DB Server 设置不同的登录账户;
        优化:改进默认本地网站,兼容SQL2005/SQL2008;
        修改:布局调整,可以最小化窗口;
        V1.6.0.0
        增加:增加多个可自动生成项;
        修改:所有可设置部分整合到一个Config.xml中;
        修改:布局调整;
        V1.5.0.0
        增加:支持自己导入数据库列表;
        优化:优化了代码,现在远程连接速度大幅度提高;
        修改:更新了SQL代码生成规则;
        修改:完善了C#实体类和存储过程的生成方案;
        修改:布局调整;
        V1.4.0.0
        增加:可以自动生成每个Table的基本SQL查询语句。
        V1.3.0.0
        优化:代码优化,调整界面和模板内容;
        修改:软件语言中文化;
        V1.2.0.0
        增加:增加了两个模板;
        优化:代码优化,修复一些Bug;
        V1.1.0.0
        优化:代码优化,加快远程连接的速度;
        修改:修复一些Bug,调整界面;
        V1.0.0.0
        增加:提供最基本的实体类生成;

最新版本获取地址:
http://www.cnblogs.com/flashbar/archive/2012/01/04/MyGenerator.html

http://www.flashbar.com.cn

有任何问题都可以联系我

QQ:12811951

Email:duluohua#hotmail.com

最后更新日期  2011/2/9 19:45

posted on 2010-09-02 22:06  Dennis.Yang  阅读(9052)  评论(28编辑  收藏  举报