微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以在 App.config

如何解决我可以在 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 作为 DB Accessing。我的问题是应用程序每次执行 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;
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。