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

标签 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 企业图书馆 5.0.414.0

最近将Enterprise Library从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, 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)

更新

这段代码对我有用:

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

最佳答案

添加引用

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/

关于database - 无法构造类型数据库。您必须配置容器以提供此值 (EntLib 5 + ODP.NET),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8847744/

相关文章:

logging - "Reliable"日志究竟是什么?

enterprise-library - ExecuteSprocAccessor 如何从存储过程返回字符串?

.NET 代码向存储在 Oracle DB 中的具有 1 或 3 个小数位的数字添加尾随 0

c# - 使用 OracleDataReader (ODAC) 返回 Oracle 存储过程

c# - 如何将来自 Web 服务的阿拉伯语值存储在数据库中

database - 在空表中查找 SQLite 列名

c# - 将参数从 DbCommand 复制到另一个 DbCommand

oracle - "Test connection succeeded"但 "An unexpected error occurred in the ODP.NET, Managed Driver"

database - 管理 H2 数据库的前端工具

php - MySQLi 连接而不指定数据库