API для изменения файла machine.config — раздел «DbProviderFactories» может отображаться только один раз для каждого файла конфигурации.

Недавно я столкнулся со следующей ошибкой на клиентской машине:

Раздел «DbProviderFactories» может отображаться только один раз для каждого файла конфигурации.

Похоже, что конфигурация машины содержит повторяющийся элемент DbProviderFactories.

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

Удаление этого дополнительного элемента вручную устраняет проблему, и наше программное обеспечение может работать. Однако нам было предложено попытаться обойти это, возможно, проигнорировав повторяющуюся запись в нашем собственном app.config. Это связано с тем, что у многих клиентов может быть одна и та же проблема, и мы не можем изменить файл конфигурации каждого.

Я попытался добавить элемент <clear/> в раздел system.data, чтобы, надеюсь, переопределить то, что уже есть в machine.config. Однако это не работает.

Например

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

Есть ли способ программно игнорировать повторяющийся элемент DbProviderFactories?

Существует ли API, позволяющий изменять конфигурацию машины?

Кто-нибудь может помочь или порекомендовать решение?

С уважением


person bobbo    schedule 14.03.2014    source источник


Ответы (3)


Недавно я столкнулся с этой же проблемой, пытаясь использовать SqlServerCe с Entity Framework.

Мне удалось обойти эту проблему с помощью доступных функций настройки на основе кода. в Entity Framework 6.

Все, что вам нужно сделать, это удалить теги <entityframeowrk> и <system.data> из вашего app.config и включить в свой проект класс, подобный следующему:

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 автоматически подберет это для вас и использует. Обратите внимание, что конфигурация в app.config перезапишет все, что появляется в этом классе.

Кроме того, если вы не хотите включать этот класс в свой уровень данных, см. раздел Перемещение DbConfiguration здесь.

person EdSalter    schedule 17.04.2014
comment
Большое спасибо за решение этой проблемы :) - person bobbo; 22.04.2014

Я столкнулся с той же проблемой, и, похоже, она вызвана драйвером IBM DB2.

Я не думаю, что вы можете игнорировать повторяющуюся запись: ошибка возникает не вашим приложением, а платформой .NET, которая не может проверить machine.config при ее чтении.

Поскольку проверка не удалась и конфигурация не загружена, вы не можете манипулировать ею через какой-либо API.

Лучше всего написать простое консольное приложение, которое не использует какой-либо поставщик данных, а также анализировать и исправлять файл конфигурации с помощью простых манипуляций с XML. Если я правильно помню, только приложения, использующие поставщиков данных, вызывают исключение, поэтому вы должны быть в состоянии это сделать; если нет, пожалуйста, дайте мне знать, чтобы я мог обновить ответ.

person Albireo    schedule 17.03.2014

Как упоминал @Albireo, проблема вызвана установкой IBM iAccess для Windows, в частности компонента .NET Provider for DB2. Я лично видел это в V7R1, но другие ссылались на ту же проблему в V6R1.

IBM знает об этой проблеме и имеет исправление в одном из сервисных выпусков.

Из документации выпуска службы V7R1:

ОПИСАНИЕ ПРОБЛЕМЫ, ИСПРАВЛЕННОЙ ДЛЯ APAR SE45767:

При неизвестных обстоятельствах повреждение XML-файла machine.config происходит при установке поставщика данных .Net (как часть полной или выборочной установки). Повреждение изолировано от частей данных XML, связанных с DbProviderFactories, и, как правило, наблюдается дублирование некоторых строк данных XML.

ПОПРАВКА ДЛЯ APAR SE45767:

Будет предоставлено превентивное исправление, которое устранит вероятную причину повреждения файла machine.config.

Исправление для обновления уже поврежденных файлов machine.config не будет предоставлено. Используйте задокументированное локальное исправление или обходной путь, если это возможно.

ОБХОД ДЛЯ APAR SE45767:

Если поставщик данных .Net не нужен, этой проблемы можно избежать, выполнив выборочную установку и не устанавливая поставщика данных .Net. Если требуется провайдер .Net, никаких обходных путей не известно. Используйте локальное исправление для решения проблемы.

person Thomas F. Abraham    schedule 17.06.2014