v9.6.2017.0808   重构正向工程,基于映射表查找数据库字段类型到实体类型的映射
大石头 authored at 2017-08-08 21:38:06
5.37 KiB
X
<#@ template language="C#" hostSpecific="true" debug="true" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml" #>
<#@ output extension=".log" #>
<#
	// 尽管T4模版可以直接调用XCoder内部类库进行代码生成,但是那会导致XCoder文件被锁定,所以采用启动进程来生成的方式!

	//var company = "XCode";
	var name = "Membership";
	var dir = "$(实体分类)";

	// 自动寻找模型文件,并从中获取公司名和链接名
	//var mdl = GetModelFile(ref company, ref name);
	//if(!File.Exists(mdl)) throw new Exception("未找到模型文件!");

	dir = "Entity";
	
	// 取得模版所在目录
	var mypath = Path.GetDirectoryName(Host.TemplateFile) + "\\";
	var mdl = mypath + "Member.xml";	// 数据模型文件

	// 计算数据模型工具XCoder位置
	var xpath = GetXPath(mypath);
	
	var exe = xpath + "XCoder.exe";
	
	var cfg = mypath + "set.config";
	var arg = String.Format("-Render -model \"{0}\" -config \"{1}\" -Log \"{2}\"", mdl, cfg, mypath + "XCoder2.log");
	WriteLine("路径:" + exe);
	WriteLine("参数:" + arg);

	var dic = new Dictionary<String, Object>();
	dic["Debug"] = false;
	dic["NameSpace"] = "XCode.Membership";// 命名空间
	dic["EntityConnName"] = name;	// 连接名
	
	dic["BaseClass"] = "Entity";	// 实体基类
	dic["RenderGenEntity"] = true;	// 生成泛型实体类
	dic["Override"] = true;			// 是否覆盖目标文件
	dic["UseCNFileName"] = true;	// 中文文件名
	dic["UseHeadTemplate"] = true;	// 使用.cs文件头模版
	// 文件头模版
	dic["HeadTemplate"] = "/*\r\n * XCoder v\<#=Version\#>\r\n * 作者:\<#=Environment.UserName + \"/\" + Environment.MachineName\#>\r\n * 时间:\<#=DateTime.Now.ToString(\"yyyy-MM-dd HH:mm:ss\")\#>\r\n * 版权:版权所有 (C) 新生命开发团队 2002~\<#=DateTime.Now.ToString(\"yyyy\")\#>\r\n*/\r\n";

	dic["OutputPath"] = mypath;					// 输出目录
	dic["TemplateName"] = "[内置]数据字典";		// 模版名
	Save(cfg, dic);
	WriteLine("生成:" + dic["TemplateName"]);
	Process.Start(exe, arg).WaitForExit(3000);

	dic["Override"] = false;					// 是否覆盖目标文件
	dic["OutputPath"] = mypath;	// 输出目录
	dic["TemplateName"] = "[内置]实体业务";		// 模版名
	Save(cfg, dic);
	WriteLine("生成:" + dic["TemplateName"]);
	Process.Start(exe, arg).WaitForExit(3000);

	dic["Override"] = true;					// 是否覆盖目标文件
	dic["UseHeadTemplate"] = false;	// 使用.cs文件头模版。实体业务一次生产的,可以要头部,实体数据要头部会导致每次生产都改变文件
	dic["TemplateName"] = "[内置]实体数据";		// 模版名
	Save(cfg, dic);
	WriteLine("生成:" + dic["TemplateName"]);
	Process.Start(exe, arg).WaitForExit(3000);

	dic["Override"] = false;					// 是否覆盖目标文件
	dic["OutputPath"] = mypath + "..\\Web\\" + name + "\\$(页面分类)";	// 输出目录
	dic["UseCNFileName"] = false;				// 中文文件名
	dic["TemplateName"] = "[内置]页面";			// 模版名
	//Save(cfg, dic);
	//WriteLine("生成:" + dic["TemplateName"]);
	//Process.Start(exe, arg).WaitForExit(3000);
#>
<#+
	String GetXPath(String mypath)
	{
		var xpath = Path.Combine(mypath, @"XCoder\");
		if(!File.Exists(xpath + "XCoder.exe")) xpath = Path.Combine(mypath, @"..\XCoder\");
		if(!File.Exists(xpath + "XCoder.exe")) xpath = Path.Combine(mypath, @"..\代码生成\");
		if(!File.Exists(xpath + "XCoder.exe")) xpath = Path.Combine(mypath, @"..\..\XCoder\");
		if(!File.Exists(xpath + "XCoder.exe")) xpath = Path.Combine(mypath, @"..\..\代码生成\");
		if(!File.Exists(xpath + "XCoder.exe")) xpath = @"C:\X\XCoder\";
		if(!File.Exists(xpath + "XCoder.exe")) xpath = @"C:\X\代码生成\";
		if(!File.Exists(xpath + "XCoder.exe")) xpath = @"D:\X\XCoder\";
		if(!File.Exists(xpath + "XCoder.exe")) xpath = @"E:\X\XCoder\";
		if(!File.Exists(xpath + "XCoder.exe")) xpath = @"F:\X\XCoder\";
		if(!File.Exists(xpath + "XCoder.exe")) throw new Exception("无法定位数据模型工具XCoder的位置!");
		xpath = Path.GetFullPath(xpath);
		
		return xpath;
	}

	// 保存字典到Xml文件,其实是变相序列化
	void Save(String file, Dictionary<String, Object> data)
	{
		var doc = new XmlDocument();
		var root = doc.CreateElement("ModelConfig");
		doc.AppendChild(root);

		if (data != null && data.Count > 0)
		{
			foreach (var item in data)
			{
				var elm = doc.CreateElement(item.Key);
				if (item.Value != null && item.Value.GetType() == typeof(Boolean))
					elm.InnerText = item.Value.ToString().ToLower();
				else
					elm.InnerText = item.Value + "";
				root.AppendChild(elm);
			}
		}
		
		File.WriteAllText(file, doc.OuterXml);
	}
	
	// 获取模型文件
	String GetModelFile(ref String company, ref String name)
	{
		// 取得模版所在目录
		var mypath = Path.GetDirectoryName(Host.TemplateFile) + "\\";

		foreach(var item in Directory.GetFiles(mypath, "*.xml"))
		{
			name = Path.GetFileNameWithoutExtension(item);
			var p = name.LastIndexOf(".");
			if(p<0) continue;

			company = name.Substring(0, p);
			name = name.Substring(p+1);

			return Path.GetFullPath(item);
		}

		return null;
	}
#>