Tro*_*ier 12 c# entity-framework using-statement nullreferenceexception objectcontext
时间再次吸引更多的思想.
我遇到了一个非常奇怪的现象.正如标题所述,我在尝试创建EF ObjectContext时遇到NullReferenceException,但是如果我在Using语句中创建上下文,我只会得到异常.我尝试了各种不同的方式,但总是一样.当然,这是直到昨天才能正常工作的代码.昨天早上我的Windows Update运行可能是相关的.
无论如何...
如果我试试这个
using (var context = new Entities(Env.Instance.Connection))
{
//do a bunch of EF stuff
}
Run Code Online (Sandbox Code Playgroud)
我在创建ObjectContext时得到NullReferenceException.这里的Env.Instance.Connection是在程序的早期创建的EntityConnection.我已经介入以确保实例和EntityConnection都存在.
如果我这样做的话
var context = new Entities(Env.Instance.Connection);
//do a bunch of EF stuff
context.Dispose();
Run Code Online (Sandbox Code Playgroud)
一切正常.
我试过了
using (var context = new Entities(Env.Instance.ConnectionName)) //the name of a connection string in my App.Config
{
//do a bunch of EF stuff
}
Run Code Online (Sandbox Code Playgroud)
我试过了
using (var context = new Entities(Env.Instance.ConnectionString)) //the actual connection string
{
//do a bunch of EF stuff
}
Run Code Online (Sandbox Code Playgroud)
我甚至试过了
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
//do a bunch of EF stuff
}
Run Code Online (Sandbox Code Playgroud)
无所谓.如果我在using语句中创建上下文,我总是会得到一个NullReferenceException.
我可以进入我的数据层的代码,然后退出ObjectContext构造函数
public Entities(string connectionString) : base(connectionString, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
Run Code Online (Sandbox Code Playgroud)
但是,一旦我退出构造函数,就会抛出错误.
思考?
编辑
在绝对最简单的迭代中,堆栈跟踪看起来像这样
在C:\ SVN\IkaPlus\IkaPlus\ViewModel\MainVM.cs中的IkaPlus.ViewModel.MainVM.ProcessMail3(对象发送者,DoWorkEventArgs e):行1371.
在C:\ SVN \中的IkaPlus.ViewModel.MainVM.RefillQueues() IkaPlus\IkaPlus\ViewModel\MainVM.cs:第832行.
理想情况下,ProcessMail3将从BackgroundWorker调用,因此它的签名,但此刻,我从主线程调用它与null参数.
为了澄清,ProcessMail3方法旨在从后台工作程序调用,这就是为什么它的签名中有sender和DoWorkEventArgs.但此刻,我直接从主线程调用它,如下所示:ProcessMail3(null,null)
我认为rism是有目共睹的.如果我这样做
private void RefillQueues()
{
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
ProcessMail3(null, null);
}
private void ProcessMail3(object sender, DoWorkEventArgs e)
{
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
}
Run Code Online (Sandbox Code Playgroud)
RefillQueues中的using语句有效,但ProcessMail3中的using语句不起作用.
编辑2
为了进一步简化,我删除了违规方法签名中的参数.所以,现在我正在打电话
private void RefillQueues()
{
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
ProcessMail3();
}
private void ProcessMail3()
{
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
}
Run Code Online (Sandbox Code Playgroud)
结果相同.在第一种方法中使用语句有效.在第二个方法中使用语句会抛出NullReferenceException.没有运行BackgroundWorkers.
编辑3
所以,我似乎找到了导致我错误的原因,尽管我仍然无法解释.
所以,我的ProcessMail3方法实际上看起来像这样(我把它重命名为EatCookies因为...我喜欢吃饼干.)
private void EatCookies()
{
#region Empty the Queue
string s = "Queue 3";
CicConnector.CreateInstance(SettingsHandler.Instance.CIC_PASSWORD,
"MYSERVER",
"C:\\temp");
//Do a bunch of stuff
#endregion
#region EF Stuff
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
我没有费心去包含其他代码行,因为当我进入方法时,我一直在踩它们.Voodoo teching,我发现如果我注释掉创建我的CiCConnector的行(不应该是相关的)我的using语句就可以了.如果未注释掉行,无论我是否实际到达该行代码,using语句都不起作用.如果我在创建字符串的行上设置断点,并跳过下一行,直接转到我的using语句,我得到NullReferenceException.如果我注释掉CiCConnector行并执行相同的操作,则using语句可以正常工作.而且,再次,如果不是使用using语句,我只是创建我的ObjectContext然后手动处理它,无论CiCConnector行如何都可以正常工作.这一切都很奇怪.
编辑4
奇怪的是,CiCConnector行如果放在第一个方法中,则不会引起奇怪的行为.所以,如果我这样做
private void RefillQueues()
{
string s = "Queue 3";
CicConnector.CreateInstance(SettingsHandler.Instance.CIC_PASSWORD,
"MYSERVER",
"C:\\temp");
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
EatCookies();
}
private void EatCookies()
{
string s = "Queue 3";
CicConnector.CreateInstance(SettingsHandler.Instance.CIC_PASSWORD,
"MYSERVER",
"C:\\temp");
using (var context = new Entities("metadata=res://*/MyDB.csdl|res://*/MyDB.ssdl|res://*/MyDB.msl;provider=System.Data.SqlClient;provider connection string=\"data source=MY-DB;initial catalog=MY-DB-PROD;persist security info=True;user id=dbuser;password=dbpass;multipleactiveresultsets=True;App=EntityFramework\""))
{
}
}
Run Code Online (Sandbox Code Playgroud)
第一种方法中的using语句工作正常,但在第二种方法中它会中断.
耸耸肩你的猜测和我一样好.可能更好.我想我只是把它当作一个奇怪的,并且根本不使用using语句.但是,如果有人有任何见解,我会很高兴找到这里发生了什么.
EF 为您管理处置,因此您自己使用或显式处置它有点多余
\n\nhttp://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html
\n\n文章摘录
\n\n\n\n在与 EF 团队的开发人员交谈之前,我的答案始终是响亮的 \xe2\x80\x9co 当然!\xe2\x80\x9d。但 DbContext\xe2\x80\x99 则不然。您不需要在 DbContext 对象上调用 Dispose 。尽管它确实实现了 IDisposable,但它只是实现了它,因此您可以在某些特殊情况下调用 Dispose 作为保护措施。默认情况下,DbContext 会自动为您管理连接。阅读全文以了解完整的故事,并了解 EF 开发人员对此有何评论。
\n