Почему платформе сущностей нужна ICollection для отложенной загрузки? - PullRequest
26 голосов
/ 19 мая 2010

Я хочу написать расширенный класс домена, такой как

public class Product    
{    
   public IEnumerable<Photo> Photos {get; private set;}    
   public void AddPhoto(){...}    
   public void RemovePhoto(){...}
 }

Но структура сущностей (первый подход кода V4) требует типа ICollection для отложенной загрузки!Приведенный выше код больше не работает так, как задумано, поскольку клиенты могут обойти метод AddPhoto / RemovePhoto и напрямую вызвать метод add в ICollection.Это нехорошо.

public class Product    
{    
   public ICollection<Photo> Photos {get; private set;} //Bad    
   public void AddPhoto(){...}    
   public void RemovePhoto(){...}    
 }

Попытка реализовать DDD с EF4 становится очень неприятной.Почему они выбрали ICollection для ленивой загрузки?

Как я могу преодолеть это?NHibernate предлагает мне лучший опыт DDD?

Ответы [ 3 ]

21 голосов
/ 20 мая 2010

Я думаю, что нашел решение ... Подробнее смотрите здесь: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/47296641-0426-49c2-b048-bf890c6d6af2/

По сути, вы хотите сделать тип ICollection защищенным и использовать его в качестве резервного набора для общедоступного IEnumerable

public class Product
{

   // This is a mapped property
   protected virtual ICollection<Photo> _photos { get; set; }

   // This is an un-mapped property that just wraps _photos
   public IEnumerable<Photo> Photos
   {
      get  { return _photos; }
   }

   public void AddPhoto(){...}
   public void RemovePhoto(){...}

} 

Чтобы ленивая загрузка работала, тип должен реализовывать ICollection, и доступ должен быть открытым или защищенным.

5 голосов
/ 19 мая 2010

Вы не можете вставить в IEnumerable. Это относится к EF так же, как и к вашим клиентам. Вы не должны использовать ICollection, хотя; Вы можете использовать IList или другие типы для записи. Мой совет, чтобы получить лучшее из обоих миров, состоит в том, чтобы предоставлять клиентам DTO, а не юридические лица.

2 голосов
/ 21 сентября 2011

Вы можете преодолеть это с помощью ReadOnlyCollection (Of T)

public class Product    
{  
    private IList<Photo> _photos;  
    public IList<Photo> Photos {
        get
        {
            return _photos.AsReadOnly();
        }
        private set { _photos = value; }
    }
    public void AddPhoto(){...}    
    public void RemovePhoto(){...}    
}

EDIT: ICollection<T> => IList<T>

Надеюсь, это то, что вы искали.

...