---
# System prepended metadata

title: .net 使用 Oracle 遇上的坑
tags: [Oracle]

---

---
tags: Oracle
---
# .net 使用 Oracle 遇上的坑
我們在開發時要有Oracle client 才能連上Oracle資料庫, Oracle client 有分兩種, Unmanaged 和 managed 兩種。

Unmanaged 就是使用C, C++ 開發的, 就是運行環境沒有自動管理資源回收功能, 程式員要自己寫CODE去控制資源使用、釋放. 使用的是 windows 的 oledb 介面, 以前的專案都是用unmanaged client. 運行環境的電腦必須安裝這個client, 而且所有的專案/程式都是共用這個client. 這個 unmanaged client 還挺多坑的, 可以參考黑暗大的BLOG https://blog.darkthread.net/blog/category/oracle

managed client 就是使用 .net 開發的, .net 會自動管理資源回收, 所以叫 managed. 這個就方便很多沒有那些坑, 專案可以透過nuget直接安裝相關的 dll, 每個專案有自己的 oracle client dll 就沒有那些版本問題.

最近遇上的是什麼坑呢?
為了打開一個陳年 .net formwork 2 webform 的專案, 專案是用 Visual Studio 2005 開發的. 不想再安裝 Visual Studio 2005. 用 Visual Studio 2022 打開專案, 成功遷移了. 但運行的時候卻出現了 **ORA-12154: TNS:could not resolve the connect identifier specified.** 錯誤.
再用Visual Studio 2019 打開, 能够成功運行, 但編輯aspx檔案整vs 會崩潰, 重啟. 所以只能使用vs2022.

首先覺得是跟32/64bit的問題有關, 所以在 vs 2022 找 build 32/64bit 的選項, 想把專案build成32bit. 但發現沒有這個選項. 

再來使用ProcessMonitor觀察vs 2022 和 vs 2019 運行有什麼不同, 是調用哪個 oracle client.
發現原來 vs 2022 使用的 iis express 是64 bit, vs2019 的iis express是32 bit. 而我機器原來安裝了兩個oracle client, 這個我也沒有留意. 64bit 的 iis 調用的是 64bit 的 client, 32bit 的 iis 調用的 32 bit 的 client. 而64bit client 的 TNSNAMES.ORA 裡面沒有相關的 tns entry, 自然就有ORA-12154錯誤. 然後在windows 添加 TNS_ADMIN 環境參數, 讓 oracle client 去TNS_ADMIN 指定的路徑找 TNSNAMES.ORA. 所以我把TNS_ADMIN指去了32bit oracle client 的TNSNAMES.ORA路徑, 讓 32bit 和 64bit client 共享一個TNSNAMES.ORA.

事情算是解決了, 但我在想電腦怎麼會有64bit的 oracle client, 原來我之前安裝了 oracle server express edition , 附帶了 oracle client, 但現在也不在本機使用 oracle server 了, 所以我把 oracle server 移除了. 那就連 oracle client 也移除了.

但怎麼把 64bit oracle client 裝回去可花了我好多力氣, 網上好多版本, 安裝了 64-bit ODAC OUI
https://www.oracle.com/database/technologies/dotnet-odacdev-downloads.html

才把坑填了..

> tns_admin is a parameter that can be added to change the directory path of Oracle Net Services configuration files from the default location of ORACLE_HOME\network\admin1. You can set the TNS_ADMIN environment variable to specify the location of the tnsnames.ora file and specify a service name from that file2. Setting the TNS_ADMIN environment variable to point to the location of a particular TNSNAMES.ORA file will ensure that file is used when Oracle attempts to resolve service names3.