1.生成项目文件,利用项目文件格式project.xml文件,替换掉project.xml模板里的一些内容 。不错。
把XML的解析这块用上了。
internal static void CreateProjectFile(string path, string projectName, ArrayList tableList) {
string projectXml = Utility.GetResource("DataTierGenerator.Project.xml");
XmlDocument document = new XmlDocument();
document.LoadXml(projectXml);
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable);
namespaceManager.AddNamespace(String.Empty, "http://schemas.microsoft.com/developer/msbuild/2003");
namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003");
document.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:ProjectGuid", namespaceManager).InnerText = "{" + Guid.NewGuid().ToString() + "}";
document.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:RootNamespace", namespaceManager).InnerText = projectName;
document.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:AssemblyName", namespaceManager).InnerText = projectName;
XmlNode itemGroupNode = document.SelectSingleNode("/msbuild:Project/msbuild:ItemGroup[msbuild:Compile]", namespaceManager);
foreach (Table table in tableList) {
XmlNode compileNode = document.CreateElement("Compile", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlAttribute attribute = document.CreateAttribute("Include");
attribute.Value = Utility.FormatClassName(table.Name) + ".cs";
compileNode.Attributes.Append(attribute);
itemGroupNode.AppendChild(compileNode);
}
document.Save(Path.Combine(path, projectName + ".csproj"));
}
2、生成程序集文件。利用AssemblyInfo.txt模板文件,把相关内容替换
internal static void CreateAssemblyInfo(string path, string assemblyTitle, string databaseName) {
string assemblyInfo = Utility.GetResource("DataTierGenerator.AssemblyInfo.txt");
assemblyInfo.Replace("#AssemblyTitle", assemblyTitle);
assemblyInfo.Replace("#DatabaseName", databaseName);
string propertiesDirectory = Path.Combine(path, "Properties");
if (Directory.Exists(propertiesDirectory) == false) {
Directory.CreateDirectory(propertiesDirectory);
}
File.WriteAllText(Path.Combine(propertiesDirectory, "AssemblyInfo.cs"), assemblyInfo);
}
3、生成SharpCore的.dll和.pdb文件。这个比较简单,只是把文件做个了复制
internal static void CreateSharpCore(string path) {
string sharpCoreDirectory = Path.Combine(path, "SharpCore");
if (Directory.Exists(sharpCoreDirectory) == false) {
Directory.CreateDirectory(sharpCoreDirectory);
}
Utility.WriteResourceToFile("DataTierGenerator.SharpCore.SharpCore.Data.dll", Path.Combine(sharpCoreDirectory, "SharpCore.Data.dll"));
Utility.WriteResourceToFile("DataTierGenerator.SharpCore.SharpCore.Data.pdb", Path.Combine(sharpCoreDirectory, "SharpCore.Data.pdb"));
Utility.WriteResourceToFile("DataTierGenerator.SharpCore.SharpCore.Transactions.dll", Path.Combine(sharpCoreDirectory, "SharpCore.Transactions.dll"));
Utility.WriteResourceToFile("DataTierGenerator.SharpCore.SharpCore.Transactions.pdb", Path.Combine(sharpCoreDirectory, "SharpCore.Transactions.pdb"));
}
4、生成实体类,这个是代码生成 的核心。生成了注释,变量,属性,方法和构造方法。
internal static void CreateEntityClass(Table table, string targetNamespace, string storedProcedurePrefix, string path) {
string className = Utility.FormatClassName(table.Name);
using (StreamWriter streamWriter = new StreamWriter(Path.Combine(path, className + ".cs"))) {
// Create the header for the class
streamWriter.WriteLine("using System;");
streamWriter.WriteLine("using System.Collections.Generic;");
streamWriter.WriteLine("using System.Data;");
streamWriter.WriteLine("using System.Data.SqlClient;");
streamWriter.WriteLine();
streamWriter.WriteLine("using SharpCore.Data;");
streamWriter.WriteLine();
streamWriter.WriteLine("namespace " + targetNamespace + " {");
streamWriter.WriteLine("/tpublic sealed class " + className + " {");
// Append the private members
streamWriter.WriteLine("/t/t#region Fields");
foreach (Column column in table.Columns) {
streamWriter.WriteLine("/t/tprivate " + Utility.CreateMethodParameter(column) + ";");
}
streamWriter.WriteLine("/t/t#endregion");
streamWriter.WriteLine("/t/t");
// Create an explicit public constructor
streamWriter.WriteLine("/t/t#region Constructors");
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Initializes a new instance of the " + className + " class.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic " + className + "() {");
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
// Create the "partial" constructor
int parameterCount = 0;
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Initializes a new instance of the " + className + " class.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.Write("/t/tpublic " + className + "(");
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
if (column.IsIdentity == false && column.IsRowGuidCol == false) {
streamWriter.Write(Utility.CreateMethodParameter(column));
if (i < (table.Columns.Count - 1)) {
streamWriter.Write(", ");
}
parameterCount++;
}
}
streamWriter.WriteLine(") {");
foreach (Column column in table.Columns) {
if (column.IsIdentity == false && column.IsRowGuidCol == false) {
streamWriter.WriteLine("/t/t/tthis." + Utility.FormatCamel(column.Name) + " = " + Utility.FormatCamel(column.Name) + ";");
}
}
streamWriter.WriteLine("/t/t}");
// Create the "full featured" constructor, if we haven't already
if (parameterCount < table.Columns.Count) {
streamWriter.WriteLine("/t/t");
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Initializes a new instance of the " + className + " class.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.Write("/t/tpublic " + className + "(");
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
streamWriter.Write(Utility.CreateMethodParameter(column));
if (i < (table.Columns.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(") {");
foreach (Column column in table.Columns) {
streamWriter.WriteLine("/t/t/tthis." + Utility.FormatCamel(column.Name) + " = " + Utility.FormatCamel(column.Name) + ";");
}
streamWriter.WriteLine("/t/t}");
}
streamWriter.WriteLine("/t/t#endregion");
streamWriter.WriteLine("/t/t");
// Append the public properties
streamWriter.WriteLine("/t/t#region Properties");
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
string parameter = Utility.CreateMethodParameter(column);
string type = parameter.Split(' ')[0];
string name = parameter.Split(' ')[1];
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Gets or sets the " + Utility.FormatPascal(name) + " value.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic " + type + " " + Utility.FormatPascal(name) + " {");
streamWriter.WriteLine("/t/t/tget { return " + name + "; }");
streamWriter.WriteLine("/t/t/tset { " + name + " = value; }");
streamWriter.WriteLine("/t/t}");
if (i < (table.Columns.Count - 1)) {
streamWriter.WriteLine("/t/t");
}
}
streamWriter.WriteLine("/t/t#endregion");
streamWriter.WriteLine("/t/t");
// Append the access methods
streamWriter.WriteLine("/t/t#region Methods");
CreateInsertMethod(table, storedProcedurePrefix, streamWriter);
CreateUpdateMethod(table, storedProcedurePrefix, streamWriter);
CreateDeleteMethod(table, storedProcedurePrefix, streamWriter);
CreateDeleteAllByMethods(table, storedProcedurePrefix, streamWriter);
CreateSelectMethod(table, storedProcedurePrefix, streamWriter);
CreateSelectAllMethod(table, storedProcedurePrefix, streamWriter);
CreateSelectAllByMethods(table, storedProcedurePrefix, streamWriter);
CreateMakeMethod(table, streamWriter);
streamWriter.WriteLine("/t/t#endregion");
// Close out the class and namespace
streamWriter.WriteLine("/t}");
streamWriter.WriteLine("}");
}
}
5、生成插入方法,在返回值上有变化,这里提供三种 int ,long,Guid
private static void CreateInsertMethod(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
string className = Utility.FormatClassName(table.Name);
string variableName = Utility.FormatCamel(className);
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Saves a record to the " + table.Name + " table.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic void Insert() {");
bool hasReturnValue = false;
foreach (Column column in table.Columns) {
if (column.IsIdentity || column.IsRowGuidCol) {
if (column.IsIdentity && Convert.ToInt32(column.Length) == 4) {
streamWriter.Write("/t/t/t" + Utility.FormatCamel(column.Name) + " = (int) SqlClientUtility.ExecuteScalar(/"" + table.Name + "Insert/", ");
hasReturnValue = true;
} else if (column.IsIdentity && Convert.ToInt32(column.Length) == 8) {
streamWriter.Write("/t/t/t" + Utility.FormatCamel(column.Name) + " = (long) SqlClientUtility.ExecuteScalar(/"" + table.Name + "Insert/", ");
hasReturnValue = true;
} else if (column.IsRowGuidCol) {
streamWriter.Write("/t/t/t" + Utility.FormatCamel(column.Name) + " = (Guid) SqlClientUtility.ExecuteScalar(/"" + table.Name + "Insert/", ");
hasReturnValue = true;
}
}
}
if (hasReturnValue == false) {
streamWriter.Write("/t/t/tSqlClientUtility.ExecuteNonQuery(/"" + table.Name + "Insert/", ");
}
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
if (column.IsIdentity == false && column.IsRowGuidCol == false) {
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (table.Columns.Count - 1)) {
streamWriter.Write(", ");
}
}
}
streamWriter.WriteLine(");");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
6、生成更新方法,
private static void CreateUpdateMethod(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
if (table.PrimaryKeys.Count > 0 && table.Columns.Count != table.PrimaryKeys.Count && table.Columns.Count != table.ForeignKeys.Count) {
string className = Utility.FormatClassName(table.Name);
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Updates a record in the " + table.Name + " table.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic void Update() {");
streamWriter.Write("/t/t/tSqlClientUtility.ExecuteNonQuery(/"" + table.Name + "Update/", ");
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (table.Columns.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(");");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
7、生成删除方法
private static void CreateDeleteMethod(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
if (table.PrimaryKeys.Count > 0) {
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Deletes a record from the " + table.Name + " table by its primary key.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic void Delete() {");
// Append the stored procedure execution
streamWriter.Write("/t/t/tSqlClientUtility.ExecuteNonQuery(/"" + table.Name + "Delete/", ");
for (int i = 0; i < table.PrimaryKeys.Count; i++) {
Column column = (Column) table.PrimaryKeys[i];
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (table.PrimaryKeys.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(");");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
8、生成所有的有条件删除的方法,包括主键和外键条件
private static void CreateDeleteAllByMethods(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
// Create a stored procedure for each foreign key
foreach (ArrayList compositeKeyList in table.ForeignKeys.Values) {
// Create the stored procedure name
StringBuilder stringBuilder = new StringBuilder(255);
stringBuilder.Append("DeleteAllBy");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
if (i > 0) {
stringBuilder.Append("_" + Utility.FormatPascal(column.Name));
} else {
stringBuilder.Append(Utility.FormatPascal(column.Name));
}
}
string methodName = stringBuilder.ToString();
string procedureName = storedProcedurePrefix + table.Name + methodName;
// Create the delete function based on keys
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Deletes a record from the " + table.Name + " table by a foreign key.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.Write("/t/tpublic static void " + methodName + "(");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
streamWriter.Write(Utility.CreateMethodParameter(column));
if (i < (compositeKeyList.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(") {");
// Append the stored procedure execution
streamWriter.Write("/t/t/tSqlClientUtility.ExecuteNonQuery(/"" + procedureName + "/", ");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (compositeKeyList.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(");");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
9、生成查询全部的方法,
private static void CreateSelectAllMethod(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
if (table.Columns.Count != table.PrimaryKeys.Count && table.Columns.Count != table.ForeignKeys.Count) {
string className = Utility.FormatClassName(table.Name);
string dtoVariableName = Utility.FormatCamel(className);
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Selects all records from the " + table.Name + " table.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tpublic static List<" + className + "> SelectAll() {");
// Append the stored procedure execution
streamWriter.WriteLine("/t/t/tusing (SqlDataReader dataReader = SqlClientUtility.ExecuteReader(/"" + table.Name + "SelectAll/")) {");
streamWriter.WriteLine("/t/t/t/tList<" + className +"> " + dtoVariableName + "List = new List<" + className + ">();");
streamWriter.WriteLine("/t/t/t/twhile (dataReader.Read()) {");
streamWriter.WriteLine("/t/t/t/t/t" + className + " " + dtoVariableName + " = Make" + className + "(dataReader);");
streamWriter.WriteLine("/t/t/t/t/t" + dtoVariableName + "List.Add(" + dtoVariableName + ");");
streamWriter.WriteLine("/t/t/t/t}");
streamWriter.WriteLine("/t/t/t/treturn " + dtoVariableName + "List;");
streamWriter.WriteLine("/t/t/t}");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
10、生成按主键查询的方法
private static void CreateSelectMethod(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
if (table.PrimaryKeys.Count > 0 && table.Columns.Count != table.ForeignKeys.Count) {
string className = Utility.FormatClassName(table.Name);
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Selects a single record from the " + table.Name + " table.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.Write("/t/tpublic static " + className + " Select(");
for (int i = 0; i < table.PrimaryKeys.Count; i++) {
Column column = (Column) table.PrimaryKeys[i];
streamWriter.Write(Utility.CreateMethodParameter(column));
if (i < (table.PrimaryKeys.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(") {");
// Append the stored procedure execution
streamWriter.Write("/t/t/tusing (SqlDataReader dataReader = SqlClientUtility.ExecuteReader(/"" + table.Name + "Select/", ");
for (int i = 0; i < table.PrimaryKeys.Count; i++) {
Column column = (Column) table.PrimaryKeys[i];
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (table.PrimaryKeys.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(")) {");
streamWriter.WriteLine("/t/t/t/tif (dataReader.Read()) {");
streamWriter.WriteLine("/t/t/t/t/treturn Make" + className + "(dataReader);");
streamWriter.WriteLine("/t/t/t/t} else {");
streamWriter.WriteLine("/t/t/t/t/treturn null;");
streamWriter.WriteLine("/t/t/t/t}");
streamWriter.WriteLine("/t/t/t}");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
11、生成按其它外键或唯一键的查询方法
private static void CreateSelectAllByMethods(Table table, string storedProcedurePrefix, StreamWriter streamWriter) {
string className = Utility.FormatClassName(table.Name);
string dtoVariableName = Utility.FormatCamel(className);
// Create a stored procedure for each foreign key
foreach (ArrayList compositeKeyList in table.ForeignKeys.Values) {
// Create the stored procedure name
StringBuilder stringBuilder = new StringBuilder(255);
stringBuilder.Append("SelectAllBy");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
if (i > 0) {
stringBuilder.Append("_" + Utility.FormatPascal(column.Name));
} else {
stringBuilder.Append(Utility.FormatPascal(column.Name));
}
}
string methodName = stringBuilder.ToString();
string procedureName = storedProcedurePrefix + table.Name + methodName;
// Create the select function based on keys
// Append the method header
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Selects all records from the " + table.Name + " table by a foreign key.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.Write("/t/tpublic static List<" + className + "> " + methodName + "(");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
streamWriter.Write(Utility.CreateMethodParameter(column));
if (i < (compositeKeyList.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(") {");
// Append the stored procedure execution
streamWriter.Write("/t/t/tusing (SqlDataReader dataReader = SqlClientUtility.ExecuteReader(/"" + procedureName + "/", ");
for (int i = 0; i < compositeKeyList.Count; i++) {
Column column = (Column) compositeKeyList[i];
streamWriter.Write(Utility.FormatCamel(column.Name));
if (i < (compositeKeyList.Count - 1)) {
streamWriter.Write(", ");
}
}
streamWriter.WriteLine(")) {");
streamWriter.WriteLine("/t/t/t/tList<" + className + "> " + dtoVariableName + "List = new List<" + className + ">();");
streamWriter.WriteLine("/t/t/t/twhile (dataReader.Read()) {");
streamWriter.WriteLine("/t/t/t/t/t" + className + " " + dtoVariableName + " = Make" + className + "(dataReader);");
streamWriter.WriteLine("/t/t/t/t/t" + dtoVariableName + "List.Add(" + dtoVariableName + ");");
streamWriter.WriteLine("/t/t/t/t}");
streamWriter.WriteLine("/t/t/t/treturn " + dtoVariableName + "List;");
streamWriter.WriteLine("/t/t/t}");
// Append the method footer
streamWriter.WriteLine("/t/t}");
streamWriter.WriteLine("/t/t");
}
}
12、生成 “制作表对象”的文件
private static void CreateMakeMethod(Table table, StreamWriter streamWriter) {
string className = Utility.FormatClassName(table.Name);
string dtoVariableName = Utility.FormatCamel(className);
streamWriter.WriteLine("/t/t/// <summary>");
streamWriter.WriteLine("/t/t/// Creates a new instance of the " + table.Name + " class and populates it with data from the specified SqlDataReader.");
streamWriter.WriteLine("/t/t/// </summary>");
streamWriter.WriteLine("/t/tprivate static " + className + " Make" + className + "(SqlDataReader dataReader) {");
streamWriter.WriteLine("/t/t/t" + className + " " + dtoVariableName + " = new " + className + "();");
streamWriter.WriteLine("/t/t/t");
for (int i = 0; i < table.Columns.Count; i++) {
Column column = (Column) table.Columns[i];
string columnNamePascal = Utility.FormatPascal(column.Name);
streamWriter.WriteLine("/t/t/tif (dataReader.IsDBNull(" + i.ToString() + ") == false) {");
streamWriter.WriteLine("/t/t/t/t" + dtoVariableName + "." + columnNamePascal + " = dataReader." + Utility.CreateGetXxxMethod(column) + "(" + i.ToString() + ");");
streamWriter.WriteLine("/t/t/t}");
}
streamWriter.WriteLine();
streamWriter.WriteLine("/t/t/treturn " + dtoVariableName + ";");
streamWriter.WriteLine("/t/t}");
}