首頁>Club>
14
回覆列表
  • 1 # 使用者4560503286646

    在使用 ADO.NET 驅動程式之前,應該確保該驅動程式已安裝並能正確執行。該驅動程式的當前版本可以使用 Informix Client Software Developer"s Kit (SDK) 2.90 來安裝。與以前的 2.81 版本不同,此 SDK 版本包括預設的 ADO.NET 驅動程式。SDK 的安裝程式也會警告您有關事項。它並不真正在您的計算機上查詢 .NET 框架的安裝,只是警告您必須在安裝 SDK 之前安裝好 .NET 框架。如果您已經安裝了 2.81 SDK,那麼最好先解除安裝它。這兩個版本無法共存。還要認識到的一點是,在將 2.90 ADO.NET 驅動程式新增到 Visual Studio Projects 中時,它會不正確地報告它自己是版本 2.81。

    2.9 版本是在 2.81 版本之上的一次重要升級。它包括一個新的 IfxDataAdapter 嚮導、IPv6 支援和一些用於 Informix 資料型別(IfxDateTime、IfxDecimal、IfxBlob 和 IfxClob)的新類。該文件更為完善,內容總量是以前的兩倍。

    要點:IBM Informix ADO.NET 驅動程式並不僅僅包含在安裝目錄下的 /bin 目錄下的 IBM.Data.Informix.dll 檔案中。顯然,它使用了由 SDK 安裝的其他客戶端程式碼。這意味著您必須在所有將使用 ADO.NET 驅動程式的機器上安裝 Informix Client SDK。您不能只在您的發行版中包括 IBM.Data.Informix.dll。這對一些應用程式而言可能是一個嚴重的限制。您還需要仔細檢查 SDK 安裝程式 (SetNet32),以定義 Informix 資料來源。

    在將 ADO.NET 驅動程式用於連線之前,還必須執行一個叫做 cdotnet.sql 的儲存過程。這個儲存過程位於 SDK 安裝的 /etc 目錄中。這類似於設定 OLEDB 驅動程式的過程,儘管這個過程更短一些。這個過程記錄在 User"s Guide 中。(請參閱下面的 參考資料 部分。)

    在完成安裝之後,檢查一下驅動程式,確保建立了連線。要在 Visual Studio 專案中使用 ADO.NET 驅動程式,則必須確保已將一個引用新增到客戶端 SDK 安裝的 /bin 目錄中找到的 IBM.Data.Informix.dll 中。正確的 using 語句是:using IBM.Data.Informix。以下是一個演示如何獲得到資料庫的連線的簡單方法:

    清單 1. 到 Informix 資料庫的連線public void MakeConnection() { string ConnectionString = "Host=" + HOST + "; " + "Service=" + SERVICENUM + "; " + "Server=" + SERVER + "; " + "Database=" + DATABASE + "; " + "User; " + "Password=" + PASSWORD + "; "; //Can add other DB parameters here like DELIMIDENT, DB_LOCALE etc //Full list in Client SDK"s .Net Provider Reference Guide p 3:13 IfxConnection conn = new IfxConnection(); conn.ConnectionString = ConnectionString; try { conn.Open(); Console.WriteLine("Made connection!"); Console.ReadLine(); } catch (IfxException ex) { Console.WriteLine("Problem with connection attempt: " + ex.Message); }}

    示例程式碼中包括一個用於此功能的 BasicConnection 類。如您所見,ConnectionString 只是一個用於連線的分號分隔的引數列表。Open() 方法打開了到資料庫的連線,如果連線失敗,則丟擲一個 IfxException。IfxException.Message 屬性通常提供關於失敗原因的合理數量的詳細資訊

    基本命令

    一旦建立了連線,就可以開始對資料庫執行命令。要做到這一點,需要使用 IfxCommand 物件。IfxCommand 的建構函式接收一個字串(SQL 命令文字)和一個 IfxConnection 作為引數。IfxCommand 物件有一系列的 Execute 方法,以便對資料庫執行命令。要清除連線,可以使用 IfxConnection.Close() 方法。以下是執行某個不返回結果集的簡單命令的例子。該命令可能是 insert、update 或 delete。

    清單 2. 執行 insert、update 或 delete 命令IfxCommand cmd;cmd = new IfxCommand("insert into test values (1, 2, "ABC")",conn);cmd.CommandTimeout = 200; //seconds to wait for command to finishtry { int rows = cmd.ExecuteNonQuery();}catch (IfxException ex) { Console.WriteLine("Error "+ex.Message);}

    ExecuteNonQuery 以整數形式返回受命令影響的行數。您還可以構建引數化語句和查詢,後面部分將對它們進行研究。注意 IfxCommand 的 CommandTimeout 屬性。預設超時時間是 30 秒,儘管在文件中沒有對此進行說明。除非更改此屬性,否則執行 30 秒後,命令就會超時,並且將丟擲一個異常。

    下一個例子是執行一條 select 語句,並處理由資料庫伺服器返回的結果集。對於快速的、只向前透過結果的遊標,可以使用由 ExecuteReader 方法返回的 IfxDataReader。不過,每個 IfxConnection 只可以有一個開啟的 IfxDataReader。(這是一條 ADO.NET 限制,不是 Informix ADO.NET 驅動程式的特定限制。)

    清單 3. 迭代透過 IfxDataReaderIfxCommand cmd = new IfxCommand("select * from test",bconn.conn);try { IfxDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { int a = dr.GetInt32(0); int b = Convert.ToInt32(dr["b"]); string c = (String)dr[2]; } dr.Close();}catch (IfxException ex) { Console.WriteLine("Error "+ex.Message);}

    每一列都被作為一般的 Object 型別進行檢索。正如程式碼所演示的,存在一些將列 Objects 轉換為正確資料型別的方法。您可以使用 IfxDataReader 的 GetXxx 方法。對於每種資料型別,幾乎都有相應的方法。GetXxx 方法將列數目作為一個引數。可以使用 IfxDataReader 的索引,透過列的名稱來訪問列。如果可能的話,.NET 框架的 Convert 函式可以將這些 Objects 轉換為正確的型別。最後,可以根據列編號為這些列建立索引,並直接強制轉換結果(對於某些型別)。

    下一個例子將展示如何呼叫需要一個引數值的儲存過程。

    清單 4. 執行帶有一個引數的儲存過程IfxCommand cmd = new IfxCommand("test_proc",conn);cmd.CommandType = CommandType.StoredProcedure; //from System.Datacmd.Parameters.Add("in_parameter",2); //many ways to create thesetry { cmd.ExecuteScalar();}catch (IfxException ifxe) { Console.WriteLine("Error "+ifxe.Message);}

    對於此 IfxCommand,必須將 CommandType 設定為來自 System.Data 中的 CommandType 列舉的 StoredProcedure 值。為了建立引數,可以使用 IfxCommand 的 Parameters.Add 方法。IfxCommands.Parameters 是一個集合,因此您可以新增您所需數量的引數。您可以使用任意 IfxParameter() 建構函式來建立引數,或者可以像上面這樣簡化引數的建立。不過要注意的是,每個 IfxParameter 都與一個特定的 IfxCommand 相關。您不能先建立 IfxParameters,然後在多個 IfxCommand 物件中使用它們。ExecuteScalar() 方法現在只返回 1。這一示例沒有從儲存過程返回任何東西。

    要構建一個不執行儲存過程的引數化 SQL 語句,需要將問號作為佔位符插入 CommandText 中。例如:

    清單 5. 引數化查詢IfxCommand insCmd = new IfxCommand("insert into clientstest " + "(clientcode, clientacctname, primarycontact, primaddrcode, " + "initialamt,createdate) values (0,?,?,?,?,TODAY)",conn);

    按照 IfxParameter 物件在命令文字中的順序,將這些物件新增到 IfxCommand 的 Parameters 集合中。在下面的擴充套件示例中的最終強型別化 DataSets 中,將進一步演示此技術。

    強型別資料集

    ADO.NET 包括一個叫做 DataSet 的專用資料庫物件。它是一個記憶體資料庫。DataSet 由一個或多個(由一些 DataRow 物件的)DataTable 物件組成。DataTable 可以透過主鍵和外來鍵相關聯。可以對資料設定一些約束。DataSet 也與實際的資料儲存斷開連線,可以透過一個或多個 DataAdapter(每個 DataTable 一個)來填充它,然後在記憶體中儲存這些資料和所有更改。稍後,DataAdapter 可以將這些更改提交回資料儲存。

    基本的 DataSet 不是強型別的。它不知道資料庫的實際行和列是什麼。因此編譯器沒有檢查這些列名稱。直到執行的時候,列名稱中的任何錯誤才會顯現出來。此外,當開發者記不清列名是 "itemcode" 還是 "itemid" 的時候,他會發現基本的 DataSet 在這方面毫無幫助。

    一個強型別的 DataSet 可以解決這些問題。而一個普通的 DataRow 卻無法取代它,因為普通的 DataRow 只有一個(例如)作為 OrderDetailDataTable 一部分的 OrderDetailDataRow。您可以將這些列作為 OrderDetailDataRow 的實際屬性 (row.ItemCode) 進行引用。用這種方式,可以提高 IntelliSense 的生產率。表名稱和列名稱在屬性編輯器中也會變得有效,從而增強諸如資料繫結之類的設計人員級工具。

    那麼,怎樣構建這個提高生產率的強型別 DataSet 呢?要花費如此多的時間或精力來構建一個您還沒有體驗到任何淨生產效率的東西嗎?Informix ADO.NET 驅動程式可能沒有其他一些驅動程式那麼複雜。Microsoft 的 SQLDataAdapter(用於 SQL Server)包括一個 Generate DataSet 嚮導。而 IfxDataAdapter 沒有這樣的嚮導。不過,您可以構建一些工具來幫助您,也可以使用一些已在 .NET 框架中構建的工具。最後,您將擁有封裝所有資料庫互動的強型別 DataSet 的一個子代。

    .NET 框架包括一個 XSD 編譯器 (xsd.exe),它可以從某個經過特殊格式化的 .xsd 檔案中生成一個強型別 DataSet。但是,誰想鍵入一串 XML 呢?幸運的是,DataSet 物件包括一個叫做 WriteXmlSchema() 的方法。此方法允許您使用非型別化的 DataSet 為強型別 DataSet 建立 XSD 檔案。讓我們來看一下如何做到這一點。以下是一個示例表:

    清單 6. Clientstest 表CREATE TABLE clientstest ( clientcode SERIAL not null, clientacctname CHAR(60) not null, primarycontact CHAR(30) not null, primaddrcode CHAR(10), createdate DATE, initialamt DECIMAL (18,0)); 以下是用於此表的單表 DataSet :清單 7. 定義 DataSetDS = new DataSet("dsClients");//main table definitionDataTable mainTable = new DataTable("clients");DataColumnCollection cols = mainTable.Columns;DataColumn column = cols.Add("clientcode",typeof(Int32));column.AllowDBNull = false;cols.Add("clientacctname",typeof(String)).MaxLength = 60;cols.Add("primarycontact",typeof(String)).MaxLength = 30;cols.Add("primaddrcode",typeof(String)).MaxLength = 10;cols.Add("initialamt",typeof(Decimal));cols.Add("createdate",typeof(System.DateTime));//primary keymainTable.PrimaryKey = new DataColumn[] {cols["clientcode"]};//add table to DataSetDS.Tables.Add(mainTable);//Write schema to fileDS.WriteXmlSchema("dsClients.xsd");

    在這個定義中,可以在資料上設定型別和限制條件。還可以設定列名稱。這些名稱不必與資料庫的列名稱匹配。觀察本文 下載 部分中的程式碼檔案,以檢視得到的 dsClients.xsd 檔案。

    為了使生成 XSD 檔案(或者在發生更改後重新生成它)變得更容易,可以為這些 DataSet Builders 構建一個框架。(完成此任務所需的所有程式碼都包含在下面部分。)在想用該框架確定要構建哪些 Builders 時,可以使用反射來動態確定某一 Builders 是否是 DataSetBuilder。讓我們從編寫 IBuildable 介面開始。它定義了 DataSetBuilder 必須實現的屬性和方法。

    清單 8. IBuildable 介面public interface IBuildable { string FileName {get; set;} string FilePath {get; set;} Logger Log {get; set;} DataSet DS {get; set;} void BuildXSD(); void CompileXSD(string outputDirectory);}

  • 中秋節和大豐收的關聯?
  • 高原反應的定義是什麼?