在本函數中,我們遍歷實體Lexington注冊列表,找到所有沒有裝備數據庫操 作幫助器的實體類型,添加到RecordTypes列表中,然後調用GenerateCode函數生成C#代碼。
我們確定編譯過程要引用的程序集,Mscorlib.dll,System.dll,System.Data.dll 是基本的必不可少的引用,所有的參與動態編譯的實體對象類型所在的程序集也得引用,快 速ORM框架本身所在的程序集也得引用。將所有的引用信息添加到options的 ReferencedAssemblIEs列表中,這裡的options變量是編譯使用的參數。然後我們使用 myWriter.ToString()獲得代碼生成器生成的C#源代碼文本。我們創建一個 CSharpCodeProvider對象,准備編譯了,對於微軟.NET框架1.1和2.0其調用過程是不同的。 對於微軟.Net框架1.1,其調用過程為
Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler compiler = provider.CreateCompiler ();
System.CodeDom.Compiler.CompilerResults result = compiler.CompileAssemblyFromSource( options , strSource );
而對 微軟.Net框架2.0其調用過程為
Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.CompilerResults result = provider.CompileAssemblyFromSource(options, strSource);
這體現了微 軟.NET框架1.1和2.0之間的差別。但微軟.NET框架2.0是兼容1.1的,因此用於微軟.NET1.1的 代碼可以在微軟.Net2.0下編譯通過,但編譯器會提示警告信息。
這裡調用 CompileAssemblyFromSource實際上就是調用微軟.Net框架中的基於命令行的C#程序編譯器 csc.exe的封裝。其內部會根據編譯器參數options保存的信息生成命令行文本然後啟動 csc.exe進程。然後將csc.exe的輸出結果保存在CompilerResults對象中。
若一切順 利,則使用CompilerResults.CompiledAssembly就能獲得編譯後生成的程序集,然後我們使 用反射操作,對每一個實體類型從動態編譯生成的程序集中獲得對應的數據庫幫助器的類型 ,然後使用System.Activator.CreateInstance函數就能實例化一個數據庫操作幫助器,將這 個幫助器放置在實體類型注冊列表中等待下次選用。
操作數據庫
我們使用動 態編譯技術獲得了數據庫操作幫助器,現在我們就使用這些幫助器來實現高速的ORM操作。
查詢數據 ReadObjects
快速ORM框架中,定義了一個ReadObjects的函數,用 於從數據庫中讀取數據並生成若干個實體對象,其代碼為
public System.Collections.ArrayList ReadObjects( string strSQL , Type RecordType )
{
this.CheckConnection();
if( strSQL == null )
{
throw new ArgumentNullException("strSQL");
}
if( RecordType == null )
{
throw new ArgumentNullException("RecordType");
}
RecordORMHelper helper = this.GetHelper( RecordType );
using( System.Data.IDbCommand cmd = this.Connection.CreateCommand())
{
cmd.CommandText = strSQL ;
System.Data.IDataReader reader = cmd.ExecuteReader();
System.Collections.ArrayList list = helper.ReadRecords( reader , 0 );
reader.Close();
return list ;
}
}
private void CheckConnection()
{
if( myConnection == null )
{
throw new InvalidOperationException("Connection is null");
}
if( myConnection.State != System.Data.ConnectionState.Open )
{
throw new InvalidOperationException ("Connection is not opened");
}
}