Kiq*_*net 7 database enterprise-library data-access odp.net enterprise-library-5
我使用企业库的ODP.NET和4.1版本与2008年相比.一切都很好.
现在,使用ODP.NET Oracle.DataAccess 4.112.2.0和企业库版本5.0.414.0以及2010,.net 4.0进行迁移.
Oracle.DataAccess 4.112.2.0 EnterpriseLibrary 5.0.414.0
在最近从Enterprise 4.1的4.1版升级到5.0之后,一旦我们收到以下错误:
"无法构建类型数据库.您必须配置容器以提供此值."
Microsoft.Practices.ServiceLocation.ActivationException:尝试获取数据库类型的实例时出现激活错误,键"ConnectionStrings.Oracle.xxx"---> Microsoft.Practices.Unity.ResolutionFailedException:依赖项的解析失败,type ="Microsoft .Practices.EnterpriseLibrary.Data.Database",name ="ConnectionStrings.Oracle.xxx".在解决时发生异常:例外情况是:InvalidOperationException - 无法构造数据库类型.您必须配置容器以提供此值.
参考文献EntLib论坛:http://entlib.codeplex.com/discussions/215290
有关它的任何解决方案
我的配置
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=709072f976b4c05b"/>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings,Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=709072f976b4c05b" />
</configSections>
<dataConfiguration defaultDatabase="ConnectionStrings.Oracle.xxx"/>
<connectionStrings>
<add name="ConnectionStrings.Oracle.xxx" connectionString="DATA SOURCE=des;PASSWORD=zzz;PERSIST SECURITY INFO=True;USER ID=aaa;"
providerName="Oracle.DataAccess.Client" />
Run Code Online (Sandbox Code Playgroud)
我的守则
var key = "ConnectionStrings.Oracle.xxx";
Database db = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<Database>(key); //~(EntLib 5 recommended)
using (DbCommand cm = db.GetStoredProcCommand("TBL_FRKDATA.TBL_FRKDATA_FND_ALL"))
{
cm.Parameters.Add(CreateCursorParameter("P_REFCURSOR"));
// Using "using" will cause both the DataReader and connection to be
// closed. (ExecuteReader will close the connection when the
// DataReader is closed.)
using (IDataReader dataReader = db.ExecuteReader(cm))
{
while (dataReader.Read())
{
builder.Add(dataReader);
}
return builder.EntityList;
}
}
Run Code Online (Sandbox Code Playgroud)
完整错误堆栈跟踪
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.GuardTypeIsNonPrimitive(IBuilderContext context,SelectedConstructor selectedConstructor)Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy. CreatePlan(IBuilderContext context,NamedTypeBuildKey buildKey)Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t,Object existing ,,字符串名称,IEnumerable
1 resolverOverrides) Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides)Microsoft.Practices.Unity.UnityContainer.Resolve(Type t,String name,ResolverOverride [] resolverOverrides)Microsoft.Practices.Unity.UnityServiceLocator.DoGetInstance(Type serviceType,String key)Microsoft.Practi ces.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型serviceType,String key)Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType,String key)Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance [TService](String key)
UPDATE
这段代码适合我:
[TestMethod]
public void Conectar_con_EntLib_y_OdpNet_Test()
{
var key = "ConnectionStrings.Oracle.xxx";
string connectionString = ConfigurationManager.ConnectionStrings[key].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings[key].ProviderName;
//Database db = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<Database>(key);
TestContext.WriteLine("connectionString: " + connectionString);
TestContext.WriteLine("providerName: " + providerName);
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
TestContext.WriteLine("Estado Conexión: " + connection.State);
connection.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案:作者:Randy Levy(http://entlib.codeplex.com/discussions/215290)
您不能将企业库OracleDatabase与Oracle.DataAccess.Client提供程序一起使用.内置的OracleDatabase被硬编码为使用OracleClientFactory DbProviderFactory,而您希望使用ODP.NET提供程序(Oracle.DataAccess.Client).
最好的方法是使EntLibContrib Oracle ODP.NET数据提供程序正常工作,因为它应该支持您需要的所有内容,包括配置文件.
由于看起来您可以创建DbProviderFactory,您可以尝试将GenericDatabase与ODP.NET OracleClientFactory一起使用,但我猜您会遇到特定Oracle功能的问题(例如refcursor).
您可以直接使用它:
string connectionString = ConfigurationManager.ConnectionStrings["Connection String"].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings["Connection String"].ProviderName;
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
var db = new GenericDatabase(connectionString, factory);
Run Code Online (Sandbox Code Playgroud)
小智 2
添加参考
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Data
Microsoft.Practices.ServiceLocation
Run Code Online (Sandbox Code Playgroud)
然后使用这一行来获取数据库:
var database = EnterpriseLibraryContainer.Current.GetInstance<Database>();
Run Code Online (Sandbox Code Playgroud)
更多信息在这里:http://devstuffs.wordpress.com/2012/03/13/enterprise-library-5-with-odp-net/