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

发布于 2024-12-26 15:18:20 字数 5978 浏览 2 评论 0原文

我使用 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 Library 版本 4.1 升级到 5.0 后,我们收到以下错误:

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

Microsoft.Practices.ServiceLocation.ActivationException:激活 尝试获取数据库键类型的实例时发生错误 “ConnectionStrings.Oracle.xxx”---> Microsoft.Practices.Unity.ResolutionFailedException:解决 依赖失败,类型= “Microsoft.Practices.EnterpriseLibrary.Data.Database”,名称= “ConnectionStrings.Oracle.xxx”。 while 发生异常: 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 构建密钥) Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext 语境) Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext 上下文)Microsoft.Practices.Unity.UnityContainer.DoBuildUp(类型 t, 对象已存在,字符串名称,IEnumerable1 解析器覆盖) Microsoft.Practices.Unity.UnityContainer.DoBuildUp(类型 t,对象 现有,字符串名称,IEnumerable1 解析器覆盖) Microsoft.Practices.Unity.UnityContainer.Resolve(类型 t,字符串名称, ResolverOverride[] 解析器Overrides) 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();
        }



    }

解决方案:兰迪·利维(http://entlib.codeplex.com/ Discuss/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);

I use ODP.NET and version 4.1 of the Enterprise Library, vs 2008. And all is OK.

Now, migrate using ODP.NET Oracle.DataAccess 4.112.2.0 and version 5.0.414.0 of the Enterprise Library, vs 2010, .net 4.0.

Oracle.DataAccess 4.112.2.0
EnterpriseLibrary 5.0.414.0

Following a recent upgrade from version 4.1 to 5.0 of the Enterprise Library, once we get the following error:

"The type Database cannot be constructed. You must configure the container to supply this value."

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.

References EntLib Forum: http://entlib.codeplex.com/discussions/215290

any solution about it ??

my config

<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" />

My Code

 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;

                }
            } 

full error stacktrace

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, 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

this code works for me:

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



    }

Solution: by Randy Levy (http://entlib.codeplex.com/discussions/215290)

You can't use the Enterprise Library OracleDatabase with the Oracle.DataAccess.Client provider. The built in OracleDatabase is hardcoded to
use the OracleClientFactory DbProviderFactory whereas you want to use the ODP.NET provider (Oracle.DataAccess.Client).

The best way is to get the EntLibContrib Oracle ODP.NET Data Provider working since it should support everything that you need including configuration files.

Since it looks like you can create the DbProviderFactory you could try to use a GenericDatabase with the ODP.NET OracleClientFactory but I would guess that
you would run into issues for specific Oracle functionality (e.g. refcursor).

You could use it directly:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

书间行客 2025-01-02 15:18:21

添加引用,

Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Data
Microsoft.Practices.ServiceLocation

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

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

更多信息请参见:

Add a reference to

Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Data
Microsoft.Practices.ServiceLocation

then use this line to get the database:

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

More info here: http://devstuffs.wordpress.com/2012/03/13/enterprise-library-5-with-odp-net/

ら栖息 2025-01-02 15:18:21

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

I had the same problem and resolve changing the Application Pool "Enable 32 bit Applications" to true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文