我使用企业库的ODP.NET和4.1版本,对比2008年。并且一切正常。
现在,使用Enterprise Library的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
在最近从企业库版本4.1升级到5.0之后,一旦出现以下错误:
“数据库类型无法构建,您必须配置容器以提供此值。”
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.
参考EntLib论坛:http://entlib.codeplex.com/discussions/215290
任何解决方案?
我的配置
providerName="Oracle.DataAccess.Client" />我的代码
var key = "ConnectionStrings.Oracle.xxx";
Database db = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance(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;
}
}完整的错误堆栈跟踪
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, IEnumerable1 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.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
这段代码适用于我:
[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(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();
}
}解答:兰迪列维(http://entlib.codeplex.com/discussions/215290)
您不能将Enterprise Library 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);