我使用企業庫的ODP.NET和版本4.1,與2008年一樣。無法構建數據庫類型。您必須配置容器以提供此值(EntLib 5 + ODP.NET)
現在,使用企業庫的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
任何關於它的解決方案?
我的配置
<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" />
我的代碼
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;
}
}
完整的錯誤堆棧跟蹤
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
此代碼的工作對我來說:
[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();
}
}
解決方案:由蘭迪·利維(http://entlib.codeplex.com/discussions/215290)
不能與Oracle.DataAccess.Client提供商使用企業庫Oracle數據庫。內置的Oracle數據庫被硬編碼爲 使用OracleClientFactory DbProviderFactory,而您想使用ODP.NET提供程序(Oracle.DataAccess.Client)。
最好的方法是讓EntLibContrib Oracle ODP.NET數據提供程序工作,因爲它應該支持您需要的所有內容,包括配置文件。
因爲它看起來像您可以創建DbProviderFactory,你可以嘗試使用與ODP.NET OracleClientFactory一個GenericDatabase,但我猜想, 你會碰上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);
快速檢查[MSDN Post](http://msdn.microsoft.com/en-us/library/ff953187(v = PandP.50).aspx)。不過,請記住,.NET Framework 4.0版中不推薦使用OracleClient提供程序,儘管它仍受Enterprise Library支持。對於未來的開發,請考慮選擇一個不同的Oracle驅動程序。' – 2012-01-13 08:41:09
您是否檢查過http://stackoverflow.com/questions/4030436/activation-error-occured-while-trying-to-get-instance-of-type-database- key或http://stackoverflow.com/questions/2900403/activation-error-occured-while-trying-to-get-instance-of-type-logwriter – 2012-01-13 08:54:21
System.Data.OracleClient.dll在.NET 4.0中已棄用。但.NET 4.0支持ODP.NET(Oracle.DataAccess.dll)。問題是使用Oracle.DataAccess.dll 4.112.2.0和EntLib 5.0。 – Kiquenet 2012-01-13 09:50:25