Получение вновь добавленных объектов из ObjectContext перед сохранением изменений - PullRequest
2 голосов
/ 03 августа 2011

ОК, я прочитал это:

EntityFramework показывает объекты перед сохранением изменений

Где добавленные объекты хранятся в ObjectContext?

Я полагаю, что нет четкого решения проблемы (хотя второе сообщение относится к 2009 году), но я думаю, что это важная проблема Entity Framework, поэтому я задам свой вопрос, несмотря на все.

Допустим, у нас есть такой код:

// Get somehow an UnitOfWork instance, e.g. using factory

var categoryRepository = new CategoryRepository(unitOfWork);
var newCategory = new Category("Some Category");
categoryRepository.Add(newCategory);
var allCategories = categoryRepository.GetAll();
Debug.Assert(allCategories.Contains(newCategory));

unitOfWork.Commit();

Если мы используем NHibernate, реализация UnitOfWork будет инкапсулировать экземпляр ISession. И данный код будет вести себя так, как мы ожидаем - мы можем получить вновь добавленную категорию из репозитория (то есть лежащего в основе ISession) до того, как изменения будут зафиксированы.

Я был удивлен, обнаружив, что Entity Framework ведет себя иначе. Если наша реализация UnitOfWork инкапсулирует ObjectContext EF, утверждение не выполняется. Перед вызовом ObjectContext.SaveChages () (в методе unitOfWork.Commit ()) новая добавленная категория недоступна (через тот же ObjectContext). Я попытался найти какое-то свойство ObjectContext, которое настраивало бы это поведение, но не удалось.

Так что мой вопрос: возможно ли получить объекты из ObjectContext, который мы только что добавили, без необходимости вызывать ObjectContext.SaveChages () (потому что мы не хотим фиксировать, пока не закончится бизнес-операция)? Если ответ «Нет», не является ли это нарушением шаблона проектирования Identity Map в частности и шаблона UnitOfWork в целом? А если вы используете EF, как справиться с этим сценарием?

Заранее спасибо.


Извините за задержку, ребята.

Кажется, вы не поняли мою точку зрения. Вопрос не в том, «Как вернуть этот экземпляр, который я только что добавил?» Ведь у меня есть ссылка на это. Вопрос заключается в том, как любой вновь добавленный (все еще не принятый - и на самом деле это возможно никогда не быть зафиксированным) объект будет рассмотрен любым запросом по данному DbSet?

Если я добавлю новую категорию, а затем напишу что-то подобное (я намеренно не использую здесь репозиторий, но строка DbContext (или ObjectContext, если мы используем EF 4.0) будет более понятной для вас):

var selectedCategories = context.Categories.Where(c => c.ParentCategory.Name == "Some Category Name");

Я хочу, чтобы моя новая категория возвращалась в наборе результатов, если она удовлетворяла условию. Вероятно, этот запрос будет выполнен другим методом (или даже другим классом), которые просто используют один и тот же контекст (хранилище) в рамках одной транзакции (единицы работы). Я знаю, что могу выполнить тот же запрос через Categories.Local, отфильтровать результат только по вновь добавленным объектам (поскольку Local содержит все объекты набора, которые в настоящее время отслеживаются) и объединить его с результатом, возвращенным из базы данных. Тебе не кажется, что это ужасно безобразно? И я даже не уверен, что я что-то не упускаю прямо сейчас. Все это работа ОРМ. Все дело в поведении транзакций (единице работы), и ORM должен справиться с этим (как это делает NHibernate).

Теперь это имеет для вас смысл?

...