【问题标题】:The type Database cannot be constructed. You must configure the container to supply this value (EntLib 5 + ODP.NET)无法构造类型数据库。您必须配置容器以提供此值 (EntLib 5 + ODP.NET)
【发布时间】:2012-02-09 11:45:02
【问题描述】:

我使用 ODP.NET 和 4.1 版的 Enterprise Library,与 2008 相比。一切正常。

现在,使用企业库的 ODP.NET Oracle.DataAccess 4.112.2.0 和版本 5.0.414.0 迁移,与 2010 年的 .net 4.0 相比。

Oracle.DataAccess 4.112.2.0 企业库 5.0.414.0

在最近从 Enterprise Library 4.1 升级到 5.0 之后,我们收到以下错误:

“无法构造类型数据库。您必须配置容器以提供此值。”

Microsoft.Practices.ServiceLocation.ActivationException:激活 尝试获取数据库类型的实例时发生错误,键 “连接字符串.Oracle.xxx”---> Microsoft.Practices.Unity.ResolutionFailedException:解决 依赖失败,类型 = “Microsoft.Practices.EnterpriseLibrary.Data.Database”,名称 = “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 上下文,SelectedConstructor selectedConstructor) Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext 语境) Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext 语境) Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext 上下文,NamedTypeBuildKey buildKey) Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext 语境) Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext 上下文)Microsoft.Practices.Unity.UnityContainer.DoBuildUp(类型 t, 对象存在,字符串名称,IEnumerable1 resolverOverrides) Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides) Microsoft.Practices.Unity.UnityContainer.Resolve(类型 t,字符串名称, ResolverOverride[] resolverOverrides) Microsoft.Practices.Unity.UnityServiceLocator.DoGetInstance(类型 服务类型,字符串键) Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型 服务类型,字符串键) Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型 服务类型,字符串键) 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);

【问题讨论】:

  • 快速检查MSDN Post。州However, keep in mind that the OracleClient provider is deprecated in version 4.0 of the .NET Framework, although it is still supported by Enterprise Library. For future development, consider choosing a different Oracle driver.
  • 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。
  • 我使用了 EntLib Config Wiz,当我添加 Oracle Connection String 时,它会添加 &lt;section name="oracleConnectionSettings" type="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.Configuration.OracleConnectionSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /&gt;&lt;oracleConnectionSettings&gt;。你可以试试 EntLib Config Wiz 吗?

标签: database enterprise-library odp.net data-access enterprise-library-5


【解决方案1】:

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

【讨论】:

  • 这是否出现在 Windows 服务上(所以不是专门“启用 32 位应用程序”)。但它是“编译为 32 位的代码,服务器只有 64 位 Oracle 客户端”。我们将代码重新编译为 64 位,并且能够部署到服务器并且它工作正常。
【解决方案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/

【讨论】:

  • 在此之后我仍然收到错误消息。我还根据其他答案在构建和 IIS 中强制使用 32 位和 64 位。
猜你喜欢
  • 2015-12-23
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多