再一次吸引更多人的思想。
我遇到了一种非常奇怪的现象。正如标题所述,我在尝试创建EF ObjectContext时得到NullReferenceException,但是如果我在Using语句中创建上下文,我只会得到异常。我尝试过各种不同的方式,但总是一样。当然,这是直到昨天才能正常工作的代码。我的Windows Update在昨天早上运行可能是相关的。
总之...
如果我试试这个
using (var context = new Entities(Env.Instance.Connection))
{
//do a bunch of EF stuff
}
我在创建ObjectContext时得到NullReferenceException。这里的Env.Instance.Connection是在程序的早期创建的EntityConnection。我已逐步确保实例和EntityConnection都存在。
如果我这样做的话
var context = new Entities(Env.Instance.Connection);
//do a bunch of EF stuff
context.Dispose();
一切正常。
我已经尝试了
using (var context = new Entities(Env.Instance.ConnectionName)) //the name of a connection string in my App.Config
{
//do a bunch of EF stuff
}
我已经尝试了
using (var context = new Entities(Env.Instance.ConnectionString)) //the actual connection string
{
//do a bunch of 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\""))
{
//do a bunch of EF stuff
}
没关系。如果我在using语句中创建上下文,我总是会得到一个NullReferenceException。
我可以进入数据层的代码,然后退出ObjectContext构造函数
public Entities(string connectionString) : base(connectionString, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
但是,一旦我退出构造函数,就会抛出错误。
思想?
修改
在绝对最简单的迭代中,堆栈跟踪看起来像这样
at IkaPlus.ViewModel.MainVM.ProcessMail3(Object sender, DoWorkEventArgs e)在C:\ SVN \ IkaPlus \ IkaPlus \ ViewModel \ MainVM.cs:Line 1371
在C:\ SVN \ IkaPlus \ IkaPlus \ ViewModel \ MainVM.cs中的IkaPlus.ViewModel.MainVM.RefillQueues():第832行。
理想情况下,ProcessMail3将从BackgroundWorker调用,因此它的签名,但此刻,我从主线程调用null参数。
为了澄清,ProcessMail3方法意图从后台工作者调用,这就是为什么它的签名中有发件人和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\""))
{
}
}
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\""))
{
}
}
相同的结果。在第一种方法中使用语句有效。在第二个方法中使用语句会抛出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
}
我还没有想要包含其他代码行,因为我在进入方法时已经踩过它们。 Voodoo teching,我发现如果我注释掉创建我的CiCConnector的行(不应该是相关的)我的使用声明工作正常后。如果行ISN&T已被注释掉,无论我是否实际到达该行代码,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\""))
{
}
}
第一种方法中的using语句工作正常,但在第二种方法中它会中断。
耸肩你的猜测和我一样好。可能更好。我想我只是把它当作一个奇怪的,并且根本不使用using语句。但是,如果有人有任何见解,我会很高兴找到这里发生的事情。
答案 0 :(得分:1)
EF为您管理处置,因此您可以自行使用或明确处置它
http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html
文章中的Snippit
在我与EF团队的开发者交谈之前,我的答案总是响亮的“当然!”。但是DbContext并不是这样。您不需要在DbContext对象上调用Dispose时具有宗教信仰。尽管它确实实现了IDisposable,但它只实现了它,所以你可以在某些特殊情况下调用Dispose作为安全措施。默认情况下,DbContext会自动为您管理连接。阅读到最后,听听完整的故事,看看EF开发者对此有何看法。