自從學會Managed ODP.NET,它馬上成為我的奧林匹克指定資料庫元件。不用額外安裝Oracle Client,管它x86還是x64,只要在主機設好TNSNAMES.ORA(我慣用的做法是用%TNS_ADMIN%環境參數提供路徑,一台主機只要設一次,部署到不同主機時不需改config),用NuGet下載安裝好一切搞定,十分方便。比起傳統ODP.NET常常糾結於x84與x64與Oracle Client版號高低,Managed ODP.NET高雅先進,用過之後就回不去了。

不過,我常遇到一個小問題,使用NuGet安裝Managed ODP.NET會自動在web.config加以下區段宣告:

<configSections>
    <section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</configSections>

在Visual Studio裡以IIS Express執行會出現以下錯誤:

Error Code       0x800700b7
設定錯誤       定義了重複的 'oracle.manageddataaccess.client' 區段
設定檔案       \\ ? \X:\TFS\src\Forms\web.config

研判machine.config已定義過oracle.manageddataaccess.client區段 ,我加上<!--把它註解掉,IIS Express即可正常執行。為了方便測試,我還習慣將同一專案路徑也掛在IIS下,好處是不需要在Visual Studio按F5/Run/Debug就能測試,還可開放其他同事預覽(IIS Express僅限localhost存取)。有趣的事發生了,網站在IIS出現以下錯誤: 

錯誤碼       0x80070032
設定錯誤       無法讀取設定區段 'oracle.manageddataaccess.client',因為它缺少區段宣告
設定檔案       \\ ? \X:\TFS\src\Forms\web.config

在IIS Express裡加oracle.manageddataaccess.client區段會出錯,拿掉區段宣告在IIS裡會出錯,你們搞得我好亂…

不過仔細一想,啊,machine.config!32與64!

IIS Express之所以抱怨區段重複宣告是因為machine.config已經宣告過,IIS抱怨缺少區段宣告則是因為machine.config沒宣告,到底machine.config有宣告還是沒有宣告?答案是一個有宣告,一個沒宣告!machine.config有分x86與x64版本,分別位於C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config 及 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config。IIS Express一律以32位元模式執行,IIS的執行環境由AppPool設定決定,預設為64位元模式。之前為了寫文章,執行過Managed ODP.NET安裝install_odpm.bat c:\oracle x86 true,只裝了x86版,導致只有32位元版machine.config加入oracle.manageddataaccess.client區段宣告,64位元版machine.config沒有,全案宣告偵破!

找出原因一切好辦,要解決有兩個做法:

  1. 執行install_odpm.bat c:\oracle both true,讓32/64 machine.config一致。
  2. NuGet之所以修改web.config加入區段宣告,是因為它加了一段範例設定:
      <oracle.manageddataaccess.client>
        <version number="*">
          <dataSources>
            <dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) " />
          </dataSources>
        </version>
      </oracle.manageddataaccess.client>
    如果不需要這段設定(像我就是用環境變數解決),將它連同一開始的configSection都移除也能避開問題。

提醒,類似的情境也會發生在部署到測試機與正式機時,需依部署對象machine.config狀況(記得區分32或64)決定是否加上configSection宣告。


Comments

# by 西瓜

感謝黑大,最近遇到的問題解決了!! 另外想請教一個問題 使用 pl sql developer 還是需要安裝 oracle client 才能執行 是否有推薦查詢oracle的工具?謝謝!

# by Jeffrey

to 西瓜,我的開發環境都有裝 Oracle Client,倒是沒有研究過不裝 Oracle Client 的做法。如果是簡單的SELECT查詢,倒是可以考慮用LINQPad+IQ Connection,參考: http://kevintsengtw.blogspot.tw/2013/03/linqpad-iq-driver-for-mysql-sqlite.html 再不然自己用 C# 寫個簡單的 Windows Form/WPF 查詢工具也是辦法。

# by 西瓜

to Jeffrey,謝謝您的回覆! 來用看看LINQPad~

Post a comment