Подтвердить что ты не робот

Как настроить трассировку EF на объектах ObjectContext без передачи имени соединения

Я пишу многоразовый класс базового репозитория, где разработчик будет проходить в общем представлении ObjectContext, а базовый репозиторий создаст экземпляр его с помощью Activator.CreateInstance. При отладке я хочу использовать пакет nuget CommunityEFProviderWrappers.EFTracingProvider. Поэтому мой код для настройки контекста объекта выглядит следующим образом:

    public void RenewDataContext()
    {
#if DEBUG
        // get the default container name
        var containerName = Activator.CreateInstance<T>().DefaultContainerName;

        // create an instance of the object context using EF Trace
        Context = (T)Activator.CreateInstance(typeof(T), EFTracingProviderUtils.CreateTracedEntityConnection(containerName));
        Context.EnableTracing();

#else
        Context = Activator.CreateInstance<T>();
#endif
    }

Проблема заключается в том, что это всегда вызывает следующую ошибку при попытке создать экземпляр ObjectContext с помощью EFTracingProvider: "Указанная схема неверна. Ошибки:\r\n (0,0): ошибка 0175: указанный поставщик магазина не может быть найден в конфигурации или недействителен."

Если я заменил имя контейнера именем строки подключения в веб-конфигурации и не сделаю первый Activator.CreateInstance<T>(), тогда он отлично работает. Поэтому проблема связана с тем, что я создаю первый экземпляр, а затем второй.

Вот что я пробовал:

  • удалить и исключить первый экземпляр.
  • закрыть соединение в первом экземпляре.
  • помещает первый экземпляр в оператор using.
  • явно определить сборку, содержащую ObjectContext в строка подключения в файле web.config в проекте запуска (Исключение Metadata при использовании Entity Framework Entity Connection)

Я пытаюсь избежать пропуска разработчика в родовом типе ObjectContext И имени строки подключения. Это кажется излишним.

Итак, мой вопрос: Как получить имя соединения из общего представления, представляющего контекст объекта, и по-прежнему использовать его для создания экземпляра контекста объекта с помощью EntityConnection, сгенерированного EF Trace?

Мой вопрос в том, почему этот метод не работает, а не о возможной работе вокруг.

4b9b3361

Ответ 1

Вот ваше решение, добавьте следующий код в ваш файл конфигурации:

<system.data>
  <DbProviderFactories>
    <add name="EF Caching Data Provider"
         invariant="EFCachingProvider"
         description="Caching Provider Wrapper"
         type="EFCachingProvider.EFCachingProviderFactory, EFCachingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
    <add name="EF Tracing Data Provider"
         invariant="EFTracingProvider"
         description="Tracing Provider Wrapper"
         type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
    <add name="EF Generic Provider Wrapper"
         invariant="EFProviderWrapper"
         description="Generic Provider Wrapper"
         type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
  </DbProviderFactories>
</system.data>

Проблема возникает в методе EFTracingProviderUtils.CreateTracedEntityConnection. Он ищет .Net Framework Data Provider - EFTracingProvider, который должен быть указан в вашем файле конфигурации. Когда он не может найти его, он не может построить такую ​​строку соединения для своих целей:

" метаданные = читатель://998e0526-8372-4bf9-83d3-949dececce96; Поставщик = EFTracingProvider; строка подключения поставщика =\"wrappedProvider =; источник данных =.\SQLEXPRESS; attachdbfilename = | DataDirectory |\database.mdf; интегрированная безопасность = True; timeout = 30; user instance = True; multipleactiveresultsets = True; App = EntityFramework\ ";"

Как вы можете видеть, читатель метаданных указал ему эту строку соединения, здесь будет MetadataException, которое возникает, когда EF не может найти EFTracingProvider. Это просто проблема с сторонним методом.

Вы можете вызвать следующий метод и получить тот же результат без каких-либо изменений в вашей конфигурации:

EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(containerName, new string[]{});

Ответ 2

Не совсем прямой ответ.

Я бы не рекомендовал предположение о жестком кодексе, что такая конфигурация существует:

(T)Activator.CreateInstance(typeof(T), EFTracingProviderUtils.CreateTracedEntityConnection(containerName));

Есть довольно редкие случаи (за пределами простых примеров), когда люди хранят строку подключения EF к файлам конфигурации с именем по умолчанию. Я думаю, что было бы лучше принять строку подключения или применить какое-то соглашение.

FYI. DbContext не раскрывает DefaultContainerName напрямую. Для этого вам нужно сначала получить ObjectContext.

Ответ 3

мой друг настолько прост, что он остается незамеченным, его файл конфигурации не связан со строкой соединения в том же представлении проекта (StartUP Project), если не в asp.net web.config, и если форма окна не в приложении .config Project (View) Window Form (UI).