17

我正在编写一个可重用的基础存储库类,开发人员将在其中传递一个表示 的泛型,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架构无效。错误:\r\n(0,0):错误 0175:指定的存储提供程序不能在配置中找到,或者无效。”EFTracingProvider

如果我用 web 配置中的连接字符串的名称替换containerName并且不做第一个,Activator.CreateInstance<T>()那么它工作正常。所以这个问题与我创建第一个实例然后是第二个的事实有关。

这是我尝试过的:

  1. 处置并清除第一个实例。
  2. 在第一个实例上关闭连接。
  3. 将第一个实例放在using语句中。
  4. 在启动项目的 web.config 中的连接字符串中显式定义包含 ObjectContext 的程序集(使用 Entity Framework Entity Connection 时的 MetadataException

我试图避免让开发人员传入ObjectContext连接字符串的泛型类型和名称。这似乎有点多余。

所以我的问题是:如何从表示对象上下文的泛型中获取连接名称,并且仍然能够使用它来使用 EF Trace 生成的 EntityConnection 创建对象上下文的实例?

我的问题是关于为什么这种方法不起作用,而不是关于可能的解决方法。

4

3 回答 3

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,它必须在您的配置文件中指定。当它找不到它时,它不能为其目的构建这样的连接字符串:

" metadata=reader://998e0526-8372-4bf9-83d3-949dececce96; provider=EFTracingProvider; 提供者连接字符串=\"wrappedProvider=;data source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\database.mdf; 综合安全=真;连接超时=30;用户实例=真;多个活动结果集=真;应用=实体框架\"; "

如您所见,元数据阅读器指定了它这个连接字符串,这里将是当 EF 找不到 EFTracingProvider 时抛出的 MetadataException。只是第三方方法的问题。

您可以调用 next 方法并接收相同的结果,而无需对配置进行任何更改:

EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(containerName, new string[]{});
于 2013-03-18T10:22:37.960 回答
0

我的朋友是如此简单以至于被忽视,它的配置文件不是在同一个项目视图(启动项目)中的连接字符串,如果不在 asp.net web.config 中并且如果 windows 窗体不在 app.config 项目中(视图)窗口窗体(UI)。

于 2013-07-09T05:54:05.427 回答
0

不是很直接的答案。

我不建议硬编码假设存在这样的配置:

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

当人们以默认名称将 EF 连接字符串存储到配置文件时,存在非常罕见的情况(除了简单示例之外)。我认为接受连接字符串或应用某种约定可能会更好。

供参考。DbContextDefaultContainerName直接暴露。你需要先得到ObjectContext它。

于 2013-02-20T10:22:58.153 回答