views:

345

answers:

0

The repository pattern typically has Get*() and Save() (or equivalent) methods for each object. How does this fit into the object graph in EF? Consider the following with lazy-loading POCO objects:

// EF
var orderItems = context.OrderItems.Where(oi => oi.Order.Id == 123);

// Repository
IOrderItemsRepository orderItemsRepository = new OrderItemsRepository();
var orderItems = orderItemsRepository.GetByOrderId(123);

// Used by both EF & Repository.
foreach (OrderItem item in orderItems)
{
  item.Description += " part of order 123";

  // Order retrieved with lazy-loading
  item.Order.Notes += " part of orderItem " + item.Id;
}

// EF - saves the full object graph (Order.Notes and OrderItems.Description)
context.SaveChanges()

// Repository - do I have to go through all the "graph" myself?
foreach (OrderItem item in orderItems)
{
  orderItemsRepository.Save(item);
}

// Since all orderItems have the same parent, just pick the first orderItem.Order
IOrdersRepository ordersRepository = new OrdersRepository();
ordersRepository.Save(orderItems[0].Order);

What are considered best practices? Here are some questions I have that may help narrow the answers:

Should the repository do a context.SaveChanges()? If so, then should there be a generic SaveAllChanges() instead of Save(orderItem)? If I do SaveAllChanges() and later I move to a custom solution, then I would have to duplicate lazy-loading and the "context" behavior myself, essentially "tying" myself to that EF functionality. If I don't use SaveAllChanges, then wouldn't turning off lazy loading make sense? Put another way, if I use EF proxies (for lazy loading, change tracking, etc.), I am forced to duplicate that if I leave EF. Should I turn off proxies and use the repository manually?

Thanks for any help!