问题
I've recently encountered the following error on a client machine:
The 'DbProviderFactories' section can only appear once per config file.
It appears that the machine config contains a duplicate DbProviderFactories element.
<system.data>
<DbProviderFactories>
<add name="IBM DB2 for i .NET Provider" invariant="IBM.Data.DB2.iSeries" description=".NET Framework Data Provider for IBM i" type="IBM.Data.DB2.iSeries.iDB2Factory, IBM.Data.DB2.iSeries, Version=12.0.0.0, Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26" />
</DbProviderFactories>
<DbProviderFactories />
</system.data>
Manually removing this extra element fixes the problem, and our software can run. However, it has been requested that we try and work around this by perhaps ignoring the duplicate entry inside our own app.config. This is because many clients might have the same issue, and we can't modify everyone's config file.
I've tried adding a <clear/>
element inside the system.data section, to hopefully override what's there already in the machine.config. However, this does not work.
For example
<system.data>
<clear />
<DbProviderFactories>
<add name="Microsoft SQL Server Compact Data Provider 4.0"
invariant="System.Data.SqlServerCe.4.0"
description=".NET Framework Data Provider for Microsoft SQL Server Compact"
type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
</DbProviderFactories>
</system.data>
Is there a way to programmatically ignore the duplicate DbProviderFactories element?
Does an API exist to allow you to modify the machine config?
Can anyone help, or recommend a solution?
Kind regards
回答1:
I have recently come across this same problem whilst trying to use SqlServerCe with Entity Framework.
I have managed to work around this issue by using the Code-Based configuration features available in Entity Framework 6.
All you need to do is remove the <entityframeowrk>
and <system.data>
tags from your app.config
and include a class similar to the following in your project:
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServerCompact;
using System.Data.SqlServerCe;
namespace Data
{
public class DatabaseConfiguration : DbConfiguration
{
public DatabaseConfiguration()
{
SetExecutionStrategy("System.Data.SqlServerCe.4.0", () => new DefaultExecutionStrategy());
SetProviderFactory("System.Data.SqlServerCe.4.0", new SqlCeProviderFactory());
SetProviderServices("System.Data.SqlServerCe.4.0", SqlCeProviderServices.Instance);
}
}
}
Entity framework will then automatically pick this up for you and use it. A note to watch out for is that configuration in the app.config
will overwrite anything that appears in this class.
Also if you do not want to include this class in your data layer, see the Moving DbConfiguration section here.
回答2:
I've encountered the same issue, and seems to be caused by the IBM DB2 driver.
I don't think you can ignore the duplicated entry: the error is not raised by your application, it's raised by the .NET framework which fails to validate the machine.config
when it reads it.
Because the validation fails and the configuration is not loaded, you can't manipulate it through any kind of API.
Your best shot is to write a simple console application which does not use any data provider and parse and fix the configuration file through plain XML manipulation. If I recall correctly only applications using data providers trigger the exception, so you should be able to do it; if not, please let me know so I can update the anser.
回答3:
As @Albireo mentioned, the problem is caused by installing IBM iAccess for Windows -- specifically the .NET Provider for DB2 component. I've seen it firsthand in V7R1, but others have referenced the same issue with V6R1.
IBM is aware of the problem and has a fix in one of the service releases.
From the V7R1 service release documentation:
DESCRIPTION OF PROBLEM FIXED FOR APAR SE45767 :
Under unknown circumstances, corruption to the machine.config XML file is occurring when the .Net data provider is installed (either as part of a Complete or Custom install type). The corruption is isolated to portions of the XML data related to the DbProviderFactories - and generally has been observed to include duplication of some lines of the XML data.
CORRECTION FOR APAR SE45767 :
A preventive fix will be provided which will eliminate the likely cause of the machine.config corruption.
A corrective fix to update already corrupted machine.config files will not be provided. Utilize the documented local fix or circumvention if possible.
CIRCUMVENTION FOR APAR SE45767 :
If the .Net data provider is not needed, this problem may be avoided by performing a custom install and ensuring the .Net Data provider will not be installed. If the .Net provider is required, no circumvention is known. Utilize the local fix to resolve the issue.
来源:https://stackoverflow.com/questions/22410059/api-to-modify-the-machine-config-file-dbproviderfactories-section-can-only-a