C# 如何在实体ObjectContext上设置EF跟踪而不传入连接名称

C# 如何在实体ObjectContext上设置EF跟踪而不传入连接名称,c#,linq-to-entities,C#,Linq To Entities,我正在编写一个可重用的基本存储库类,其中开发人员将传入一个表示ObjectContext的泛型,基本存储库将使用Activator.CreateInstance创建它的实例。调试时,我希望使用nuget软件包CommunityEFProviderWrappers.EFTracingProvider。因此,我设置对象上下文的代码如下所示: public void RenewDataContext() { #if DEBUG // get the default co

我正在编写一个可重用的基本存储库类,其中开发人员将传入一个表示
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
    }
公共数据上下文()
{
#如果调试
//获取默认容器名称
var containerName=Activator.CreateInstance().DefaultContainerName;
//使用EF Trace创建对象上下文的实例
Context=(T)Activator.CreateInstance(typeof(T),EFTracingProviderUtils.CreateTracedEntityConnection(containerName));
Context.EnableTracing();
#否则
Context=Activator.CreateInstance();
#恩迪夫
}
问题是,当它尝试使用
EFTracingProvider
创建
ObjectContext
的实例时,总是引发以下错误:“指定的架构无效。错误:\r\n(0,0):错误0175:在配置中找不到指定的存储提供程序,或者指定的存储提供程序无效。”

如果我在web配置中将containerName替换为连接字符串的名称,并且不执行第一个
Activator.CreateInstance()
,那么它可以正常工作。所以这个问题与我创建第一个实例和第二个实例有关

以下是我尝试过的:

  • dispose并清空第一个实例
  • 关闭第一个实例上的连接
  • 将第一个实例放在using语句中
  • 在中显式定义包含ObjectContext的程序集 启动项目中web.config中的连接字符串 ()
  • 我试图避免让开发人员传入
    ObjectContext
    的泛型类型和连接字符串的名称。这似乎有点多余

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


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

    不是真正直接的答案

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

    (T)Activator.CreateInstance(typeof(T), EFTracingProviderUtils.CreateTracedEntityConnection(containerName));
    
    当人们以默认名称将EF连接字符串存储到配置文件中时,很少会出现这种情况(除了简单的示例)。我认为最好接受连接字符串或应用某种约定


    仅供参考
    DbContext
    不直接公开
    DefaultContainerName
    。您需要首先获取
    ObjectContext

    这是您的解决方案,将以下代码添加到配置文件中:

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

    “我的朋友”非常简单,以至于它不会被注意到,它的配置文件与连接字符串不在同一个项目视图(启动项目)中,如果不在asp.net web.config中,如果windows窗体不在app.config项目(视图)windows窗体(UI)中.

    您能否共享
    \u defaultContainerName
    EFTracingProviderUtils.CreateTracedEntityConnection(\u defaultContainerName)的值
    ?\u defaultContainerName仅由该if语句中的代码初始化,因此它是由T表示的给定ObjectContext的defaultContainerName。它最初为null,因此该if语句中的代码在错误发生时运行。CreateTracedEntityConnection(_defaultContainerName)基于_defaultContainerName的值返回EntityConnection。因为所有这些的目标都是动态的,所以值取决于传入的泛型。如果连接字符串是:,那么_defaultContainerName将是“MyDataContext”。名称不是简单的类型名称,
    typeof(t)。name
    ?还是我过于简单化了?不是类型名,而是连接名。这很有意义。在我写这篇文章的公司,我们总是将连接字符串存储在配置文件中,所以我们总是有一个DefaultContainerName。我想我写这个问题的时候是在EF4上,所以我使用的是ObjectContext,而不是DbContext。在EF5中,我只是用条件将EF跟踪烘焙到T4模板中。如果您能找到一种方法来从DbWorks/ObjeCu外文实例中获得连接字符串,并且使用EfTracle创建一个新实例,而不需要上述问题,那么我会认为这是一个可接受的答案。这样做的全部目的是使其成为动态的,而不是让开发人员将其与ObjectContext一起传递。您是否可以添加一个解释,说明这应该做什么,以及这将如何成为我试图完成的工作的一个可比的解决方法?看看您的例外情况-在配置中找不到指定的存储提供程序,或者是无效的。您是否理解,您的配置文件中缺少某些内容?我希望是的。您可以在异常消息中看到它。我给了你解决方案,解释是在你的例外。如果你不知道如何使用谷歌-看看这篇文章。我做了一个快速测试,它看起来确实有效。根据我的问题,我的问题只发生在我创建objectcontext实例以获取名称时。如果我没有执行该步骤,只是将连接的名称作为字符串传递,那么在没有您建议的配置部分的情况下,它可以正常工作。你知道为什么吗?当我测试你的问题时,硬编码的连接名没有给我任何积极的结果。最后一行
    EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(containerName,新字符串[]{})非常适合我。我只是希望我能理解为什么。
    
    EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(containerName, new string[]{});