看了很多的文章,在沒有安裝oracle客戶端的機器上,使用ef連接oracle數據,動輒需要300M的dll。好吧,我承認那樣是可以的。
但是如果我開發的僅僅是一個winform程序,代碼僅僅是幾十M,這樣的程序即使開發的再好,我想也不會有人去使用。
自從vs對oracle的oracleclient過時后, oracle提供給vs的開發支持工具已經為我們提供了最簡單的dll,Oracle.ManagedDataAccess.dll。安裝odp.net后,在開發中,只需將這個dll引用即可,並允許其復制到本地,或者發布程序后,將其拷貝到本地。
程序發布后,拷貝到沒有安裝oracle客戶端的電腦上運行。出現異常:沒有提供驅動程序。
原因就是在framework的機器文件machine.config中,沒有提供驅動程序,可在其中添加如下配置
<system.data> <DbProviderFactories>
<remove invariant="ODP.NET, Managed Driver"/>
<add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" /> </DbProviderFactories> </system.data>
(注:下邊的內容其實可以不用的,只是本人用來練手的!)
但是這樣很不友好。因此我們可以把以上代碼寫入程序的配置文件中。
注意,程序的配置文件和機器配置是互斥的,也就是這段代碼只能在其中一個文件中存在,不能同時存在,也不能都存在。
因此自己寫了一段代碼,動態的處理配置
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; using System.Configuration; using System.Windows.Forms; namespace Utility { public class OracleDriverWithoutClient { private static OracleDriverWithoutClient _instance = null; /// <summary> /// 初始化oracle在配置文件中驅動 /// </summary> private OracleDriverWithoutClient() { if (!CheckFramework4MachineConfig() && !CheckAppconfig()) { //在機器配置和程序運行配置文件都沒有oracle托管驅動,那么添加 AddOracleManagedDriver(); } else if (CheckFramework4MachineConfig() && CheckAppconfig()) { //在機器配置中存在,在程序運行配置文件同時存在,那么從程序運行配置中刪除 RemoveOracleManagedDriver(); } } public static OracleDriverWithoutClient CreateInstance() { if (_instance == null) { _instance = new OracleDriverWithoutClient(); } return _instance; } /// <summary> /// 檢測機器配置未見是否已經安裝了oralce托管驅動 /// </summary> /// <returns></returns> bool CheckFramework4MachineConfig() { var machinePath = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config"; var ele = XElement.Load(machinePath); var addNodes = ele.Element("system.data").Element("DbProviderFactories").Elements("add").ToList(); if (addNodes.Any(o => o.Attribute("name").Value == "ODP.NET, Managed Driver")) { return true; } return false; } /// <summary> /// 檢測程序配置文件中是否已經存在了oracle托管驅動 /// </summary> /// <returns></returns> bool CheckAppconfig() { var configPath = AppDomain.CurrentDomain.BaseDirectory + string.Format(@"\{0}.exe.config", Application.ProductName); var appConfigElement = XElement.Load(configPath); var systemDataEle = appConfigElement.Element("system.data"); if (systemDataEle == null) return false; var dbProviderFactoriesEle = systemDataEle.Element("DbProviderFactories"); if (dbProviderFactoriesEle == null) return false; if (!dbProviderFactoriesEle.Elements("add").Where(o => o.Attribute("name").Value == "ODP.NET, Managed Driver").Any()) return false; return true; } /// <summary> /// 向程序驅動中添加oracle托管驅動配置 /// </summary> void AddOracleManagedDriver() { var configPath = AppDomain.CurrentDomain.BaseDirectory + string.Format(@"\{0}.exe.config", Application.ProductName); var appConfigElement = XElement.Load(configPath); var systemDataEle = appConfigElement.Element("system.data"); if (systemDataEle == null) { appConfigElement.Add(new XElement("system.data")); systemDataEle = appConfigElement.Element("system.data"); } var dbProviderFactoriesEle = systemDataEle.Element("DbProviderFactories"); if (dbProviderFactoriesEle == null) { systemDataEle.AddFirst(new XElement("DbProviderFactories")); dbProviderFactoriesEle = systemDataEle.Element("DbProviderFactories"); } if (!dbProviderFactoriesEle.Elements("add").Where(o => o.Attribute("name").Value == "ODP.NET, Managed Driver").Any()) { dbProviderFactoriesEle.AddFirst(new XElement("add", new object[] { new XAttribute("name", "ODP.NET, Managed Driver") , new XAttribute("invariant", "Oracle.ManagedDataAccess.Client") ,new XAttribute("description","Oracle Data Provider for .NET, Managed Driver"), new XAttribute("type","Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342")})); } appConfigElement.Save(configPath, SaveOptions.None); } /// <summary> /// 從程序配置文件中刪除oracle托管驅動配置 /// </summary> void RemoveOracleManagedDriver() { var configPath = AppDomain.CurrentDomain.BaseDirectory + string.Format(@"\{0}.exe.config", Application.ProductName); var appConfigElement = XElement.Load(configPath); var systemDataEle = appConfigElement.Element("system.data"); if (systemDataEle == null) return; var dbProviderFactoriesEle = systemDataEle.Element("DbProviderFactories"); if (dbProviderFactoriesEle == null) return; if (dbProviderFactoriesEle.Elements("add").Where(o => o.Attribute("name").Value == "ODP.NET, Managed Driver").Any()) { dbProviderFactoriesEle.Elements("add").Where(o => o.Attribute("name").Value == "ODP.NET, Managed Driver").Remove(); } appConfigElement.Save(configPath, SaveOptions.None); } } }