Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullReferenceException when creating ObjectContext in Using statement

Time once again to appeal to greater minds.

I'm experiencing a very strange phenomenon. As the title states, I'm getting a NullReferenceException when trying to create an EF ObjectContext, but I only get the exception if I create the context within a Using statement. I've tried a variety of different ways, but it always ends up the same. And, of course, this is code that worked fine up until yesterday. It could possibly be relevant that my Windows Update ran yesterday morning.

Anyway...

If I try this

using (var context = new Entities(Env.Instance.Connection))
{
    //do a bunch of EF stuff
}

I get the NullReferenceException when creating my ObjectContext. Here Env.Instance.Connection is an EntityConnection that was created earlier in the program. I've stepped through to make sure the instance and EntityConnection both exist.

If I do it this way

var context = new Entities(Env.Instance.Connection);
//do a bunch of EF stuff
context.Dispose();

Everything works fine.

I've tried

using (var context = new Entities(Env.Instance.ConnectionName)) //the name of a connection string in my App.Config
{
    //do a bunch of EF stuff
}

I've tried

using (var context = new Entities(Env.Instance.ConnectionString)) //the actual connection string
{
    //do a bunch of EF stuff
}

I've even tried

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
}

Doesn't matter. If I create the context within a using statement I always get a NullReferenceException.

I can step into the code of my data layer and I exit the ObjectContext constructor

public Entities(string connectionString) : base(connectionString, "Entities")
{
    this.ContextOptions.LazyLoadingEnabled = true;
    OnContextCreated();
}

But, as soon as I exit the constructor, the error is thrown.

Thoughts?

EDIT

In the absolute simplest iteration, the stack trace looks like so

at IkaPlus.ViewModel.MainVM.ProcessMail3(Object sender, DoWorkEventArgs e) in C:\SVN\IkaPlus\IkaPlus\ViewModel\MainVM.cs:Line 1371.
at IkaPlus.ViewModel.MainVM.RefillQueues() in C:\SVN\IkaPlus\IkaPlus\ViewModel\MainVM.cs:Line 832.

Ideally, ProcessMail3 would be called from a BackgroundWorker, thus its signature, but at the moment, I'm calling it from the main thread with null parameters.

To clarify, the ProcessMail3 method is intended to be called from a background worker, that's why it has sender and DoWorkEventArgs in its signature. But at the moment, I'm calling it directly from the main thread like so: ProcessMail3(null, null)

I think rism is on to something. If I do this

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\""))
    {
    }
}

The using statement in RefillQueues works, but the using statement in ProcessMail3 does not.

EDIT 2

To simplify it further, I've eliminated the parameters in the signature of the offending method. So, now I'm calling

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\""))
    {
    }
}

Same results. Using statement in the first method works. Using statement in the second method throws a NullReferenceException. There are no BackgroundWorkers running.

EDIT 3

So, I seem to have found what's causing my error, though I still can't explain it.

So, my ProcessMail3 method, actually looks like this (I've renamed it to EatCookies because...I like to eat cookies.)

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
}

I haven't bothered to include the other lines of code because I've been stepping over them when I enter the method. Voodoo teching, I've found that if I comment out the line which creates my CiCConnector (shouldn't be relevant) my using statement after it works fine. If the line ISN'T commented out, regardless of whether I actually reach that line of code or not, the using statement doesn't work. If I set a breakpoint on the line where I create my string, and skip over the next line, going directly to my using statement, I get the NullReferenceException. If I comment out the CiCConnector line and do the same thing, the using statement works. And, again, if instead of a using statement, I simply create my ObjectContext then dispose of it manually later, it all works fine regardless of the CiCConnector line. This is all very strange.

EDIT 4

Oddly enough, the CiCConnector line does not cause the odd behavior if it's placed in the first method. So if I do

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\""))
    {
    }
}

The using statement in the first method works fine, but in the second method it breaks.

shrug Your guess is as good as mine. Probably better. I think I'll just chalk it up as an oddity and simply not use the using statement. But, if anyone has any insight, I'd be thrilled to find out what the heck is going on here.

like image 872
Troy Frazier Avatar asked Nov 12 '15 09:11

Troy Frazier


1 Answers

EF manages the disposale for you so it is a little redundent to be using a using or explicitly disposing of it yourself

http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html

Snippit from the article

Before I talked with the devs on the EF team my answer was always a resounding “of course!”. But it’s not true with DbContext. You don’t need to be religious about calling Dispose on your DbContext objects. Even though it does implement IDisposable, it only implements it so you can call Dispose as a safeguard in some special cases. By default DbContext automatically manages the connection for you. Read to the end to hear the full story and see what the EF devs had to say about it.

like image 128
Steven Ackley Avatar answered Oct 09 '22 02:10

Steven Ackley