无法构造类型数据库。您必须配置容器以提供此值(EntLib 5 + ODP.NET)

时间:2012-01-13 08:27:02

标签: database enterprise-library odp.net data-access 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:激活   尝试获取Database,key类型的实例时发生错误   “ConnectionStrings.Oracle.xxx”--->   Microsoft.Practices.Unity.ResolutionFailedException:解析   依赖失败,type =   “Microsoft.Practices.EnterpriseLibrary.Data.Database”,name =   “ConnectionStrings.Oracle.xxx”。发生异常时:while   解析。例外情况是: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" />

我的代码

 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   上下文)   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext   上下文)   Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext   context,NamedTypeBuildKey buildKey)   Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext   上下文)   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(类型   serviceType,String key)   Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型   serviceType,String key)   Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型   serviceType,String key)   Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance [TService](字符串   键)

更新

此代码适用于我:

    [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();
        }



    }

解决方案:由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);

2 个答案:

答案 0 :(得分:2)

添加对

的引用
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Data
Microsoft.Practices.ServiceLocation

然后使用此行获取数据库:

var database = EnterpriseLibraryContainer.Current.GetInstance<Database>();

此处有更多信息:http://devstuffs.wordpress.com/2012/03/13/enterprise-library-5-with-odp-net/

答案 1 :(得分:0)

我遇到了同样的问题并决定将应用程序池“启用32位应用程序”更改为true。