Я решил свою проблему.
Позвольте мне в предисловии сказать, что я использую ASP.NET MVC - если вы пишете однопользовательское настольное приложение, ваша проблема может полностью отличаться от моей.
В моем случае я, по-видимому, придумал плохое решение проблемы, с которой столкнулся ранее.
Я создавал несколько экземпляров моего объекта-контекста - и когда вы создаете сущности с одним экземпляром и пытаетесь связать их с сущностью, созданной другим экземпляром, вы получаете странные ошибки.
Чтобы обойти это, я подумал, ну, я просто позабочусь, чтобы у меня был только один объект-контекст. Поэтому я создал класс с открытым геттером, который будет создавать экземпляр, если он еще не создан, и возвращать его. Тип одноэлементного шаблона, гарантирующий, что у меня был один объект-контекст для всего приложения.
В моем приложении я время от времени создаю «одноразовые» объекты - например, временная сущность, иногда предварительно заполненная несколькими значениями по умолчанию, просто чтобы я мог визуализировать форму. Когда форма отправлена, новый объект создается, заполняется, проверяется и затем сохраняется.
Сохранение завершится неудачно, но с ошибкой, описанной на этой странице, из-за того, что какой-то атрибут пуст, хотя я заполнил все поля и объект прошел проверку.
Проблема заключалась в том, что он не пытался сохранить объект, который я только что создал - он висел на «выбрасываемом» объекте из предыдущего запроса и пытался сначала сохранить его.
Исходя из PHP, меня поразило осознание того, что приложения ASP.NET MVC имеют жизненный цикл, очень отличный от приложений PHP. В PHP сценарии запускаются, обрабатывают запрос, заканчиваются, а затем заканчиваются - тогда как в ASP.NET они запускаются, работают некоторое время, обслуживая много запросов, а затем, в конце концов, заканчиваются и перезапускаются.
Создавая мой объект-контекст в статическом методе, я создавал не один экземпляр для запроса, а один экземпляр для приложения. Поскольку объект-контекст сохраняется между запросами, мои «одноразовые» сущности накапливаются - и, в конце концов, когда я пытаюсь сохранить SaveChanges (), он, конечно, завершится неудачей.
Эта путаница частично проистекает из того факта, что Entity Framework был написан с учетом настольных приложений - он не был разработан для жизненного цикла веб-приложения.
Вы можете обойти это, и вот решение:
public class App
{
public static MyEntities DB
{
get {
// Create (as needed) and return an object context for the current Request:
string ocKey = "MyEntities_" + HttpContext.Current.GetHashCode().ToString("x");
if (!HttpContext.Current.Items.Contains(ocKey))
HttpContext.Current.Items.Add(ocKey, new MyEntities());
return HttpContext.Current.Items[ocKey] as MyEntities;
}
}
}
Теперь вы можете получить свой объектный контекст из любого места:
MyEntities DB = MyNamespace.App.DB;
Я нашел решение в этой длинной статье, в которой рассматриваются несколько (правильных и неправильных) способов управления жизненным циклом объекта-контекста:
http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
Надеюсь, что это полезно для других: -)