迁移至Oracle.ManagedDataAccess后,为何需修改machine.config?
为什么app.config配置Oracle托管驱动后仍需修改machine.config?
出现这种情况主要和.NET配置的加载优先级、EF提供程序的查找机制以及程序集绑定规则有关,具体原因如下:
全局配置优先级高于应用级配置
machine.config是.NET的全局配置文件,所有.NET应用都会优先读取这里的配置项。如果你的machine.config中已经注册了旧版本的Oracle.ManagedDataAccess.Client或者非托管的Oracle.DataAccess.Client,即使你在app.config里添加了<remove>节点,某些场景下运行时还是会优先加载全局注册的程序集,导致版本不匹配或加载失败。配置节定义的全局依赖
oracle.manageddataaccess.client这个配置节需要先在全局配置中被识别,.NET运行时才会正确解析app.config里的对应配置。如果machine.config中没有注册这个配置节的处理程序,app.config里的配置可能在初始化阶段就无法被解析,进而导致驱动程序集加载失败。EF提供程序的查找逻辑
Entity Framework在加载数据提供程序时,会按machine.config→app.config的顺序遍历DbProviderFactories的注册项。如果全局配置中存在同名的不变量(invariant),哪怕app.config里做了移除操作,旧的注册信息可能依然会干扰驱动的加载,引发程序集找不到的异常。
无需修改machine.config的替代解决方案
如果不想修改全局配置,可以尝试以下操作:
- 确保app.config里的
<remove invariant="Oracle.ManagedDataAccess.Client" />节点放在<add>节点之前,并且配置中的版本号、公钥Token与你引用的Oracle.ManagedDataAccess程序集完全一致。 - 在app.config的
<runtime>节点中添加程序集绑定重定向,强制运行时加载指定版本的驱动:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Oracle.ManagedDataAccess" publicKeyToken="89b483f429c47342" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.122.18.3" newVersion="4.122.18.3" /> </dependentAssembly> </assemblyBinding> </runtime>
- 彻底清理项目中对非托管
Oracle.DataAccess的引用,删除bin、obj目录下的旧程序集,避免残留文件引发加载冲突。
内容的提问来源于stack exchange,提问作者Arvind
相关产品推荐
相关产品推荐

