您的位置:首页 > 数据库

关于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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: