Подтвердить что ты не робот

Исключение NullReferenceException при создании объекта ObjectContext в приложении

Время снова обратиться к большим умом.

У меня очень странное явление. Как указано в заголовке, я получаю исключение NullReferenceException при попытке создать объект ObjectContext EF, но я получаю исключение только в том случае, если создаю контекст в инструкции Using. Я пробовал разные способы, но он всегда заканчивается тем же. И, конечно же, это код, который работал до вчерашнего дня. Возможно, уместно, что мой Windows Update был запущен вчера утром.

В любом случае...

Если я попробую этот

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

Я получаю исключение NullReferenceException при создании объекта ObjectContext. Здесь 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();
}

Но, как только я выхожу из конструктора, выдается ошибка.

Мысли?

ИЗМЕНИТЬ

В абсолютной простейшей итерации трассировка стека выглядит так

в IkaPlus.ViewModel.MainVM.ProcessMail3 (отправитель объекта, DoWorkEventArgs e) в C:\SVN\IkaPlus\IkaPlus\ViewModel\MainVM.cs: Строка 1371.
   в IkaPlus.ViewModel.MainVM.RefillQueues() в C:\SVN\IkaPlus\IkaPlus\ViewModel\MainVM.cs: строка 832.

В идеале ProcessMail3 вызывается из BackgroundWorker, поэтому его подпись, но на данный момент я вызываю его из основного потока с нулевыми параметрами.

Чтобы прояснить, метод ProcessMail3 предназначен для вызова из фонового рабочего, поэтому у него есть подпись и DoWorkEventArgs в своей подписи. Но на данный момент я вызываю это прямо из основного потока, как это: ProcessMail3 (null, null)

Я думаю, что ризм что-то происходит. Если я сделаю это

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

Оператор using в RefillQueues работает, но оператор using в ProcessMail3 этого не делает.

РЕДАКТИРОВАТЬ 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. Нет фоновых рабочих файлов.

РЕДАКТИРОВАТЬ 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 (не должен быть релевантным), моя инструкция использования после того, как она работает нормально. Если строка НЕ ​​прокомментирована, независимо от того, действительно ли я нахожусь в этой строке кода или нет, оператор using не работает. Если я установил точку останова в строке, где я создаю свою строку, и пропустите следующую строку, перейдя непосредственно к моему оператору using, я получаю исключение NullReferenceException. Если я прокомментирую строку CiCConnector и сделаю то же самое, работает оператор using. И опять же, если вместо используемого оператора я просто создаю свой ObjectContext, тогда утилизирую его вручную позже, все работает отлично, независимо от линии CiCConnector. Это очень странно.

EDIT 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. Но, если у кого-то есть понимание, я был бы рад узнать, что здесь происходит.

4b9b3361

Ответ 1

EF управляет диспутами для вас, поэтому немного избыточно использовать использование или прямое распоряжение им самостоятельно

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

Снип из статьи

Прежде чем я поговорил с разработчиками команды EF, мой ответ всегда был громким "конечно!". Но это не так с DbContext. Вам не нужно быть религиозным при вызове Dispose на объекты DbContext. Несмотря на то, что он реализует IDisposable, он только реализует его, поэтому вы можете вызвать Dispose в качестве защиты в некоторых особых случаях. По умолчанию DbContext автоматически управляет соединением для вас. Прочтите до конца, чтобы услышать всю историю и посмотреть, что должны были сказать об этом разработчики EF.