关于XCode数据库反向工程的理解
2012-04-23 21:39
239 查看
陆陆续续用Xcode组件将近一年了,作为一个业余开发者,很感谢大石头和他的团队。不仅感谢他们创造如此艺术的组件,更感谢他们耐心的指点,我才学会了使用模板,来开发始于自己风格和功能的通用组件。作为了老的动软代码生成器的使用者,但我接触并学会使用Xcode后,以及2年来在博客园看到的各类开发框架和ORM,我不得不说Xcode是我见过最强大的,小巧,精悍。很早就想写一篇教程,可能是基础比较差,写不出什么高质量的文章,毕竟是业余开发者。可能我的表述很多不专业,只有我自己理解,我也只需要对自己有用的功能。今天写这篇博文主要是受大石头的启发,因为越来越多的人使用Xcode,群里面的人都爆了,但是他们又没有太多时间来重复回答这些新手的问题,所以需要大家自力更生,看源码去学会使用。为了贡献自己对Xcode的理解和使用经验,使得后来学习的人更加容易,所以才有了我的这篇文章,写得不好,请拍砖。
1.事情起因
NewLife.CommonEntity里面封装了一些通用实体类,今天自己做一个小工具(个人喜好,玩玩的),想得到这些通用实体类的数据字典,虽然知道有数据库反向工程的功能,但就是懒得动手。所以一开始手抄抄,然后在群里面哄了一下,然后群主大石头提示了一个CheckTables方法,其他的当然只能靠自己看源码了。其实往往很多帮助也只需要这么关键的一个提示,然后自己去学习。
2.关于数据库方向工程:就是通过配置文件切换数据库连接字符串,不需要任何操作,系统会根据实体类自动生成数据库及数据表。很多ORM虽然可以通过配置文件修改数据库连接字符串,但还是需要在目标数据库中新建好表,因此多少有些繁琐,而Xcode彻底屏蔽了这些东西,不必要关心数据库。因此从给一个数据库转化到另外一个数据库,是再方便不过。
3.解决过程
在石头的提示下(CheckTables),我找到了这个方法所在的类DAL(数据访问层),看看这个方法:
View Code
1 /// <summary>
2 /// 获取指定连接名下的所有实体数据表
3 /// </summary>
4 /// <param name="connName">数据库连接名称</param>
5 /// <param name="isLoadAssembly">是否加载外部程序集</param>
6 /// <returns>IDataTable集合</returns>
7 public static List<IDataTable> GetTables(String connName,bool isLoadAssembly)
8 {
9 var tables = new List<IDataTable>();
// 记录每个表名对应的实体类
var dic = new Dictionary<String, Type>(StringComparer.OrdinalIgnoreCase);
var list = new List<String>();
IEnumerable<Type> Cur = AssemblyX.FindAllPlugins(typeof(IEntity),isLoadAssembly).Where(t => TableItem.Create(t).ConnName == connName);
foreach (Type item in Cur )
{
list.Add(item.Name);
// 过滤掉第一次使用才加载的
var att = ModelCheckModeAttribute.GetCustomAttribute(item);
if (att != null && att.Mode != ModelCheckModes.CheckAllTablesWhenInit) continue;
var table = TableItem.Create(item).DataTable;
//判断表名是否已存在
Type type = null;
if (dic.TryGetValue(table.Name, out type))
{
// 两个实体类,只能要一个当前实体类是,跳过
if (IsCommonEntity(item))
continue;
// 前面那个是,排除
else if (IsCommonEntity(type))
{
dic[table.Name] = item;
// 删除原始实体类
tables.RemoveAll((tb) => tb.Name == table.Name);
}
// 两个都不是,报错吧!
else
{
String msg = String.Format("设计错误!发现表{0}同时被两个实体类({1}和{2})使用!", table.Name, type.FullName, item.FullName);
XTrace.WriteLine(msg);
throw new XCodeException(msg);
}
}
else
{
dic.Add(table.Name, item);
}
tables.Add(table);
}
if (DAL.Debug) DAL.WriteLog("[{0}]的所有实体类({1}个):{2}", connName, list.Count, String.Join(",", list.ToArray()));
return tables;
}
然后在主程序中调用 List<IDataTable> list = EntityFactory.GetTables("Common");然后一句话我要的东东都有了。呵呵,其他的就不说了。
上面主要是增加了一个参数:IEnumerable<Type> Cur = AssemblyX.FindAllPlugins(typeof(IEntity),isLoadAssembly).Where(t => TableItem.Create(t).ConnName == connName);
呵呵,建议石头把这个参数补充上去,因为也不费事,要是在4.0里面,来个默认参数。
下面是大石头对反向工程的说明:所有实体,默认情况下,根据连接名分组,只要用到这个实体,那么跟这个实体在同一个连接名旗下的所有实体,都会开始进行反向工程,建立数据库数据表。
除了CheckAllTablesWhenInit的实体,标记CheckAllTablesWhenInit的实体,主要位于CommonEntity,它们是用到之后,只会为自己这个实体创建数据表。
因为CommonEntity里面所有实体都在Common这个连接名下,然后很多时候只需要用到CommonEntity里面的部分表,而不是全部表。
附上大石头的博客和Xcode开源网址:
http://www.cnblogs.com/nnhy
http://xcode.codeplex.com/
1.事情起因
NewLife.CommonEntity里面封装了一些通用实体类,今天自己做一个小工具(个人喜好,玩玩的),想得到这些通用实体类的数据字典,虽然知道有数据库反向工程的功能,但就是懒得动手。所以一开始手抄抄,然后在群里面哄了一下,然后群主大石头提示了一个CheckTables方法,其他的当然只能靠自己看源码了。其实往往很多帮助也只需要这么关键的一个提示,然后自己去学习。
2.关于数据库方向工程:就是通过配置文件切换数据库连接字符串,不需要任何操作,系统会根据实体类自动生成数据库及数据表。很多ORM虽然可以通过配置文件修改数据库连接字符串,但还是需要在目标数据库中新建好表,因此多少有些繁琐,而Xcode彻底屏蔽了这些东西,不必要关心数据库。因此从给一个数据库转化到另外一个数据库,是再方便不过。
3.解决过程
在石头的提示下(CheckTables),我找到了这个方法所在的类DAL(数据访问层),看看这个方法:
View Code
1 /// <summary>
2 /// 获取指定连接名下的所有实体数据表
3 /// </summary>
4 /// <param name="connName">数据库连接名称</param>
5 /// <param name="isLoadAssembly">是否加载外部程序集</param>
6 /// <returns>IDataTable集合</returns>
7 public static List<IDataTable> GetTables(String connName,bool isLoadAssembly)
8 {
9 var tables = new List<IDataTable>();
// 记录每个表名对应的实体类
var dic = new Dictionary<String, Type>(StringComparer.OrdinalIgnoreCase);
var list = new List<String>();
IEnumerable<Type> Cur = AssemblyX.FindAllPlugins(typeof(IEntity),isLoadAssembly).Where(t => TableItem.Create(t).ConnName == connName);
foreach (Type item in Cur )
{
list.Add(item.Name);
// 过滤掉第一次使用才加载的
var att = ModelCheckModeAttribute.GetCustomAttribute(item);
if (att != null && att.Mode != ModelCheckModes.CheckAllTablesWhenInit) continue;
var table = TableItem.Create(item).DataTable;
//判断表名是否已存在
Type type = null;
if (dic.TryGetValue(table.Name, out type))
{
// 两个实体类,只能要一个当前实体类是,跳过
if (IsCommonEntity(item))
continue;
// 前面那个是,排除
else if (IsCommonEntity(type))
{
dic[table.Name] = item;
// 删除原始实体类
tables.RemoveAll((tb) => tb.Name == table.Name);
}
// 两个都不是,报错吧!
else
{
String msg = String.Format("设计错误!发现表{0}同时被两个实体类({1}和{2})使用!", table.Name, type.FullName, item.FullName);
XTrace.WriteLine(msg);
throw new XCodeException(msg);
}
}
else
{
dic.Add(table.Name, item);
}
tables.Add(table);
}
if (DAL.Debug) DAL.WriteLog("[{0}]的所有实体类({1}个):{2}", connName, list.Count, String.Join(",", list.ToArray()));
return tables;
}
然后在主程序中调用 List<IDataTable> list = EntityFactory.GetTables("Common");然后一句话我要的东东都有了。呵呵,其他的就不说了。
上面主要是增加了一个参数:IEnumerable<Type> Cur = AssemblyX.FindAllPlugins(typeof(IEntity),isLoadAssembly).Where(t => TableItem.Create(t).ConnName == connName);
呵呵,建议石头把这个参数补充上去,因为也不费事,要是在4.0里面,来个默认参数。
下面是大石头对反向工程的说明:所有实体,默认情况下,根据连接名分组,只要用到这个实体,那么跟这个实体在同一个连接名旗下的所有实体,都会开始进行反向工程,建立数据库数据表。
除了CheckAllTablesWhenInit的实体,标记CheckAllTablesWhenInit的实体,主要位于CommonEntity,它们是用到之后,只会为自己这个实体创建数据表。
因为CommonEntity里面所有实体都在Common这个连接名下,然后很多时候只需要用到CommonEntity里面的部分表,而不是全部表。
附上大石头的博客和Xcode开源网址:
http://www.cnblogs.com/nnhy
http://xcode.codeplex.com/
相关文章推荐
- 关于使用powerdesigner进行反向工程
- MyEclipse从数据库反向生成实体类之Hibernate方式 反向工程
- XCode工程中关于Targets的介绍
- 关于在Xcode的OC工程中相对路径失败的原因
- 关于unity导出xcode的工程中unity的内容部分。备忘录
- mybatis 通过数据库反向工程
- Xcode 7 使用CoreData 关于数据库升级问题
- 使用PowerDesigner 对现有数据库进行反向工程(图解教程二)
- XCode工程中关于Targets的介绍
- 理解 Xcode 工程
- 我对XCode之Cocosd-x工程项目的理解
- 利用visio2003进行数据库的反向工程
- 关于PowerDesigner 反向工程没有注释的解决方案
- 关于颜色直方图和反向投影的一些理解
- 用POWER DESIGNER 生成MSYQL数据库反向工程(.sql-->pdm)及由pdm生成.sql文件
- MyEclipse从数据库反向生成实体类之Hibernate方式 反向工程
- 用PowerDesigner对现有的数据库反向工程建立E-R图
- 数据库设计:关于数据库范式一些理解
- 关于MyEclipse使用Hibernate反向工程生成实体类总是在defalut包中
- 关于 xcode 工程编译报错 undefined symbol _res_9_init的解决办法