📄 codegenerator.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Data;
using Microsoft.CSharp;
using System.IO;
using OracleDALGen.Classes;
using Oracle.DataAccess.Client;
using OracleDALGen.Classes.Generator;
using OracleDALGen.Classes.Database;
using OracleDALGen.Classes.Attributes;
namespace OracleDALGen.Classes.Generator
{
public class CodeGenerator
{
private const string CreatePackage = "pkg_gen.generate_package";
private const string CreatePackageBody = "pkg_gen.generate_package_body";
private OraConnection connection;
private bool generateFromTable = true;
private bool generateTree = false;
private bool generateDBPkg = false;
private bool saveAsFile = false;
private string sql;
private string nameSpace;
private string outputDirectory;
private CodeTypeDeclaration ctd = null;
private CodeNamespace cs = null;
private CodeTypeMemberCollection foreignPropertyList = new CodeTypeMemberCollection();
private CodeTypeMemberCollection foreignFieldList = new CodeTypeMemberCollection();
private DataColumnCollection columns = null;
private Dictionary<string, ColumnInfo> columnsInfo = new Dictionary<string, ColumnInfo>();
private List<string> tableIgnoreList = new List<string>();
public CodeGenerator(string sql, string nameSpace, bool generateFromTable, bool saveAsFile, OraConnection connection)
{
this.connection = connection;
this.generateFromTable = generateFromTable;
this.nameSpace = nameSpace;
this.sql = sql;
this.saveAsFile = saveAsFile;
if (generateFromTable)
{
columns = DBUtils.LoadSQL("select * from " + sql, null, connection).Tables[0].Columns;
}
else
columns = DBUtils.LoadSQL(sql, null, connection).Tables[0].Columns;
}
private CodeGenerator(List<string> tableIgnoreList, string sql, string nameSpace, bool generateFromTable, bool saveAsFile, OraConnection connection)
: this(sql, nameSpace, generateFromTable, saveAsFile, connection)
{
this.tableIgnoreList = tableIgnoreList;
}
#region Main assembly
public string Generate(string className, bool generateTree, bool generateDBPkg)
{
return Generate(className, generateTree, generateDBPkg, null);
}
public string Generate(string className, bool generateTree, bool generateDBPkg, string outputDirectory)
{
this.generateTree = generateTree;
this.generateDBPkg = generateDBPkg;
this.outputDirectory = outputDirectory;
if (generateFromTable)
{
/*
* Table already generated, returning nothing
*/
if (tableIgnoreList.IndexOf(sql.ToLower()) != -1)
return null;
tableIgnoreList.Add(sql.ToLower());
className = GetPublicName(sql);
LoadColumnsInfo(sql);
}
/*
* Setting up imports and namespace
*/
CodeCompileUnit ccu = new CodeCompileUnit();
cs = new CodeNamespace(nameSpace);
cs.Imports.Add(new CodeNamespaceImport("System"));
cs.Imports.Add(new CodeNamespaceImport("System.Data"));
cs.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
cs.Imports.Add(new CodeNamespaceImport("OracleDALGen.Classes.Attributes"));
ccu.Namespaces.Add(cs);
ctd = new CodeTypeDeclaration(className);
cs.Types.Add(ctd);
CodeTypeMemberCollection fieldList = GenerateFields(columns);
CodeTypeMemberCollection propertyList = GenerateProperties(columns);
ctd.Members.AddRange(fieldList);
ctd.Members.AddRange(foreignFieldList);
ctd.Members.AddRange(propertyList);
ctd.Members.AddRange(foreignPropertyList);
ctd.CustomAttributes.AddRange(GenerateProcedureMappings());
/*
* Generating source code
*/
CSharpCodeProvider cscProvider = new CSharpCodeProvider();
CodeGeneratorOptions cop = new CodeGeneratorOptions();
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
cscProvider.GenerateCodeFromCompileUnit(ccu, sw, cop);
if (saveAsFile && outputDirectory != null)
{
bool dirExists = true;
if (!Directory.Exists(outputDirectory)) {
DirectoryInfo di = Directory.CreateDirectory(outputDirectory);
dirExists = di.Exists;
}
if (dirExists)
{
StreamWriter fileWriter = File.CreateText(Path.Combine(outputDirectory, GetPublicName(sql)) + ".cs");
try
{
fileWriter.Write(sb.ToString());
}
finally
{
fileWriter.Close();
}
}
}
return sb.ToString();
}
private CodeTypeDeclaration Class
{
get { return ctd; }
}
#endregion
#region Generate fields / properties
private CodeAttributeDeclarationCollection GenerateProcedureMappings()
{
CodeAttributeDeclarationCollection mappings = new CodeAttributeDeclarationCollection();
/*
[ClassDatabaseType("get_test_object", Method.Select, CommandType.StoredProcedure)]
[ClassDatabaseType("merge_test_object", Method.Merge, CommandType.StoredProcedure)]
[ClassDatabaseType("delete_test_object", Method.Delete, CommandType.StoredProcedure)]
*/
if (generateFromTable)
{
string selectProc = "select proc";
string mergeProc = "merge proc";
string deleteProc = "delete proc";
if (generateDBPkg && GenerateDBPkg(sql))
{
selectProc = string.Format("{0}$.get_{0}", sql);
mergeProc = string.Format("{0}$.merge_{0}", sql);
deleteProc = string.Format("{0}$.delete_{0}", sql);
}
mappings.Add(CreateMappingAttribute(selectProc, Method.Select, CommandType.StoredProcedure));
mappings.Add(CreateMappingAttribute(mergeProc, Method.Merge, CommandType.StoredProcedure));
mappings.Add(CreateMappingAttribute(deleteProc, Method.Delete, CommandType.StoredProcedure));
}
else if (generateDBPkg)
{
mappings.Add(CreateMappingAttribute(sql, Method.Select, CommandType.Text));
}
return mappings;
}
private CodeAttributeDeclaration CreateMappingAttribute(string procedure, Method method, CommandType cmdType)
{
CodeAttributeDeclaration cad = new CodeAttributeDeclaration(new CodeTypeReference(typeof(ClassDatabaseType)));
cad.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(procedure)));
cad.Arguments.Add(new CodeAttributeArgument(new CodeVariableReferenceExpression(method.GetType().Name + "." + method.ToString())));
cad.Arguments.Add(new CodeAttributeArgument(new CodeVariableReferenceExpression(cmdType.GetType().Name + "." + cmdType.ToString())));
return cad;
}
private CodeTypeMemberCollection GenerateFields(DataColumnCollection columns)
{
CodeTypeMemberCollection list = new CodeTypeMemberCollection();
foreach (DataColumn col in columns)
{
/*
* Adding field memebers
*/
CodeMemberField field = new CodeMemberField(col.DataType, GetPrivateName(col.ColumnName));
if (columnsInfo.ContainsKey(col.ColumnName))
{
foreach (ColumnInfo ci in columnsInfo[col.ColumnName].Links)
{
string fieldName = GetPrivateName(ci.TableName);
string className = GetPublicName(ci.TableName);
CodeMemberField listField = new CodeMemberField(string.Format("List<{0}>", className), fieldName);
listField.Attributes = MemberAttributes.Private;
foreignFieldList.Add(listField);
}
}
field.Attributes = MemberAttributes.Private;
list.Add(field);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -