Сохранить и вернуть вновь созданный объект при использовании Service и Entity Framework 4.1? - PullRequest
0 голосов
/ 28 марта 2012

Недавно мы отключили загрузку Lazy и генерацию прокси для Entity Framework. До этого, после того, как мы вносили новые изменения в EF, мы возвращали весь объектный граф. Сейчас я делаю, что после коммита я вызываю метод FindById в репозитории, чтобы вернуть новый объект (я включаю свойства навигации, которые нужно поместить обратно в новый созданный объект). У меня вопрос: это стандартная практика после создания или клиент должен отвечать за повторный вызов службы для получения вновь созданного объекта?

Способ сохранения на сервисе:

public SomeObject Create(SomeObject someObject)
{
     _repository.Add(someObject);
     _repository.UnitOfwork.Commit()

     //this did not exist when lazy loading and proxy generation were enabled.
     var newObject = _repository.FindById(someObject.Id);
     return newObject;

     //Before we would jsut return the created object because everything was loaded.
     //return someObject

}

Я просто хочу знать, является ли это наилучшей практикой после создания объекта с отложенной загрузкой и отключением создания прокси. Мне любопытно узнать, как другие разработчики справляются с этим.

1 Ответ

2 голосов
/ 28 марта 2012

Прежде чем мы вернем созданный объект, потому что все было загружен.

Почему-то я сомневаюсь, что это вообще так. Если вы звоните SaveChanges EF не выполняет запрос для загрузки свойств навигации, независимо от того, используете ли вы отложенную загрузку или нет. Например:

Предположим, у вас есть заказы с навигационной ссылкой на клиента, и в базе данных уже есть клиент с Id = 1. Теперь вы создаете заказ (отложенная загрузка включена):

var order = context.Orders.Create();
order.CustomerId = 1;
context.Orders.Add(order);
context.SaveChanges();

bool isCustomerLoaded = context.Entry(order).Reference(o => o.Customer).IsLoaded;

isCustomerLoaded будет false - если только клиент 1 уже не находится в контексте, но свойство также будет заполнено без отложенной загрузки («исправление отношений»). Конечно, как только вы получите доступ к order.Customer, он будет загружен из-за отложенной загрузки, но это происходит потом и не имеет ничего общего с SaveChanges.

Если ваш код хорошая идея или нет, зависит от того, как используется возвращаемый объект и чего ожидает потребитель. Как правило, самой близкой заменой отложенной загрузки без отложенной загрузки является явная загрузка, поскольку обе стратегии загрузки выполняют отдельные запросы для загрузки свойства навигации. Конечно, это означало бы, что вы должны ввести дополнительный код на стороне потребителя для загрузки свойств, тогда как при ленивой загрузке «это просто работает», когда вы используете свойство, и запрос происходит за кулисами в перегруженных средствах получения свойств объекта прокси. Явная загрузка выглядела бы так:

context.Entry(order).Reference(o => o.Customer).Load();
// or for collections
context.Entry(order).Collection(o => o.OrderItems).Load();

Вам приходилось вызывать это в тех местах, где вы впервые обращаетесь к свойству навигации.

Если вы заранее знаете, что объекту, возвращенному из вашего метода Create, потребуются все свойства навигации, вы можете загрузить их так, как вы предлагаете. Но это определенно изменение в шаблонах доступа к вашей базе данных по сравнению с отложенной загрузкой: для быстрой загрузки потребуется всего один запрос для загрузки всего графа объектов, но это потенциально очень дорогой запрос с большим количеством JOIN-файлов в БД и большим количеством данных. вернулся. Принимая во внимание, что ленивая загрузка и явная загрузка вызовут многократные запросы, но более простые запросы с меньшим количеством возвращаемых данных. Без учета деталей модели и проведения измерений невозможно сказать, что лучше.

...