我可以在 App.config 中指定 <entityFramework>.<providers>.<provider> 的绝对位置吗

Can I specify the absolute location for <entityFramework>.<providers>.<provider> in App.config

  <entityFramework>
    <providers>
      <provider invariantName="Devart.Data.Oracle" type="Devart.Data.Oracle.Entity.OracleEntityProviderServices, Devart.Data.Oracle.Entity.EF6, Version=9.14.1204.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

我正在为应用程序 (ESRI ArcMap) 开发插件库。同时,我想使用 EF6 作为数据库访问。我的问题是应用程序每次执行DbProviderFactories.GetFactory("Devart.Data.Oracle")就崩溃,提示错误Devart.Data.Oracle Failed to find or load the registered .Net Framework Data Provider.

我确定所有必需的库都与主要加载项 DLL 放在同一文件夹中。但是,主应用程序 exe 与加载项 DLL 不在同一个位置。应用程序似乎通过单独搜索加载项文件夹来加载其加载项 DLL。

我的观察是 DbProviderFactories.GetFactory 仅在 exe 所在的文件夹中搜索提供程序 DLL。因此,它无法找到位于加载项文件夹中的提供程序 DLL。请问有什么方法可以指定DbProviderFactories.GetFactory应该在哪里搜索提供程序DLL?

提前致谢。

DbProviderFactories注册代码:

private static void InitDbProvFactEntry() {
  bool DevartProviderRegistered = false;
  var dataSet = System.Configuration.ConfigurationManager.GetSection("system.data") as System.Data.DataSet;
  foreach (System.Data.DataRow dr in dataSet.Tables[0].Rows) {
    if ((string)dr[2] == "Devart.Data.Oracle") {
      DevartProviderRegistered = true;
    }
  }
  if (!DevartProviderRegistered) {
    dataSet.Tables[0].Rows.Add("dotConnect for Oracle"
        , "Devart dotConnect for Oracle"
        , "Devart.Data.Oracle"
        ,
        "Devart.Data.Oracle.OracleProviderFactory, Devart.Data.Oracle, Version=" + Devart.Data.Oracle.ProductInfo.Version + ", Culture=neutral, PublicKeyToken=09af7300eec23701");
  }
}

正在从 YourSubDirName 加载 Devart.* 程序集:

 AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
...
    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {

      var assemblyName = new AssemblyName(args.Name);
      if (assemblyName.Name.StartsWith("Devart.")) {
        var assembly = Assembly.GetExecutingAssembly();
        string directory = System.IO.Path.GetDirectoryName(assembly.Location);
        string newPath = Path.Combine(directory, "YourSubDirName");
        var files = Directory.EnumerateFiles(newPath);
        string targetDllName = assemblyName.Name + ".dll";
        if (files.Any(name => name.EndsWith(targetDllName))) {
          string fullFilePath = Path.Combine(newPath, targetDllName);
          return Assembly.LoadFrom(fullFilePath);
        }
      }

      return null;
    }