I use ODP.NET and version 4.1 of the Enterprise Library, vs 2008. And all is OK.
Now, migrate using ODP.NET Oracle.DataAccess 4.112.2.0 and version 5.0.414.0 of the Enterprise Library, vs 2010, .net 4.0.
Oracle.DataAccess 4.112.2.0 EnterpriseLibrary 5.0.414.0
Following a recent upgrade from version 4.1 to 5.0 of the Enterprise Library, once we get the following error:
"The type Database cannot be constructed. You must configure the container to supply this value."
Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type Database, key "ConnectionStrings.Oracle.xxx" ---> Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Microsoft.Practices.EnterpriseLibrary.Data.Database", name = "ConnectionStrings.Oracle.xxx". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type Database cannot be constructed. You must configure the container to supply this value.
References EntLib Forum: http://entlib.codeplex.com/discussions/215290
any solution about it ??
my config
<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" />
My Code
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;
}
}
full error stacktrace
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, String name, IEnumerable
1 resolverOverrides) Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable
1 resolverOverrides) Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) Microsoft.Practices.Unity.UnityServiceLocator.DoGetInstance(Type serviceType, String key) Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService](String key)
UPDATE
this code works for me:
[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();
}
}
Solution: by Randy Levy (http://entlib.codeplex.com/discussions/215290)
You can't use the Enterprise Library OracleDatabase with the Oracle.DataAccess.Client provider. The built in OracleDatabase is hardcoded to use the OracleClientFactory DbProviderFactory whereas you want to use the ODP.NET provider (Oracle.DataAccess.Client).
The best way is to get the EntLibContrib Oracle ODP.NET Data Provider working since it should support everything that you need including configuration files.
Since it looks like you can create the DbProviderFactory you could try to use a GenericDatabase with the ODP.NET OracleClientFactory but I would guess that you would run into issues for specific Oracle functionality (e.g. refcursor).
You could use it directly:
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);
Add a reference to
then use this line to get the database:
More info here: http://devstuffs.wordpress.com/2012/03/13/enterprise-library-5-with-odp-net/