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()
,那么它可以正常工作。所以这个问题与我创建第一个实例和第二个实例有关
以下是我尝试过的:
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[]{});