Как настроить трассировку 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>()
, тогда он отлично работает. Поэтому проблема связана с тем, что я создаю первый экземпляр, а затем второй.
Вот что я пробовал:
Я пытаюсь избежать пропуска разработчика в родовом типе ObjectContext
И имени строки подключения. Это кажется излишним.
Итак, мой вопрос: Как получить имя соединения из общего представления, представляющего контекст объекта, и по-прежнему использовать его для создания экземпляра контекста объекта с помощью EntityConnection, сгенерированного EF Trace?
Мой вопрос в том, почему этот метод не работает, а не о возможной работе вокруг.
Ответы
Ответ 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).