5
public class Order 
{ 
public int Id {get;set;} 
[DisplayName("User")] 
public long UserId { get; set; } 
[ForeignKey("UserId")] 
public virtual User User { get; set; } 
public decimal Amount { get; set; } 
} 

С IEnumurableКогда выставлять IEnumerable вместо ICollection?

public class User 
{ 
public int Id{get;set;} 
public virtual IEnumerable<Order> Orders { get; set; } 
} 

public User GetWithOrders() 
{ 
var myUser=UserRepository.GetByEmail("[email protected]"); 
myUser.Orders=OrderRepository.GetByUserId(myUser.Id); 
return myUser; 
} 

С ICollection

public class User 
{ 
public int Id{get;set;} 
public virtual ICollection<Order> Orders { get; set; } 
} 

public User GetWithOrders() 
{ 
var myUser=UserRepository.GetByEmail("[email protected]"); 
return myUser; 
} 

Я не отложенной загрузки, используя IEnumerable для свойства навигации. Поэтому я должен получить заказы для этого пользователя с другим запросом.

У меня есть навигация с ICollection. Поэтому я могу получать заказы от пользователя. Это кажется крутым. Но затем я могу добавлять новые заказы пользователю в Контроллер без использования службы или репозитория.

Это своего рода манипулирование данными на уровне контроллера. Это анти-шаблон?

ответ

2

Но [с ICollection] Я могу добавить новый заказ в Контроллер, не используя сервис или репозиторий.

Вы имеете в виду вы можете сделать это (при условии, что есть ViewModel для добавления заказа пользователю и SaveChanges() где-то):

public class UserController 
{ 
    public ActionResult AddUserOrder(AddUserOrderModel addOrder) 
    { 
     User user = User.GetByEmail(addOrder.UserEmail);   
     user.Orders.Add(addOrder.Order); 
     User.SaveChanges(); 
    } 
} 

И особенно, что вы можете сделать user.Orders.Add(...), то это побочный эффект раскрытия типов объектов с вашего уровня сервиса или репозитория.

Если вы хотите, чтобы избежать этого, вы должны определить и раскрыть бизнес-объект, содержащий элементы, которые вы хотите выставить:

public class UserBLL 
{ 
    public int Id { get; private set; } 
    public IEnumerable<Order> Orders { get { return _orders.AsEnumerable(); } } 
    private IEnumerable<Order> _orders; 

    public UserBLL(User user) 
    { 
     Id = user.Id; 
     _orders = user.Orders;   
    } 

    public void AddOrder(Order order) 
    { 
     _orders.Add(order); 
    } 
} 
+0

Во-первых, я подумал также viewmodel. Но я не был уверен, что это может принести больше сложности или нет. Я буду использовать viewmodels, если нужно. Благодарю. –

+0

Дело не в моделе, на самом деле. Это модель BLL или Domain. Объекты, представляющие ваш прецедент (пользователь, который может иметь заказы). Используйте это, если вы не хотите подвергать свои модели данных воздействию внешних факторов. – CodeCaster

+0

Почему вы возвращаете '_orders.AsEnumerable();' while '_orders' уже' IEnumerable '? –

1

Здесь нет реального выбора. ICollection необходим EF для управления некоторыми его аспектами, такими как привязка результатов запроса и ленивая загрузка. Используя IEnumerable, вы практически отключите все эти функции, но вместе с этим, понимание EF вашей базовой структуры. Когда вы создаете миграцию, EF не генерирует каких-либо требуемых базовых таблиц соединений для отношений M2M, внешних ключей на связанных таблицах и т. Д.

Длинные и короткие, используйте ICollection. Хотя вы правы, что это позволяет добавлять элементы, просто добавляя их в коллекцию связанного объекта, sans-DAL, они все равно не могут быть сохранены без доступа к контексту. Если вы правильно настроили свой DAL, это доступно только через DAL, поэтому вам все равно придется передать объект обратно в ваш DAL-конвейер, чтобы увековечить любое из этих изменений. Другими словами, не беспокойтесь об этом.

+0

Я использую МОК. Контекст, общий для каждого запроса. В том же запросе, если я это применил для другой цели, это может повлиять. Но вы правы. Я думаю, что у меня нет никаких действий, которые выбирают реляционный запрос, а затем сохраняют или редактируют один и тот же запрос. Если у меня есть, я буду использовать viewmodel, который сказал @CodeCaster. –

Смежные вопросы