我可以在 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;
}
<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;
}