Почему инфраструктура сущности нуждается в ICollection для ленивой загрузки?
Я хочу написать богатый класс домена, например
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?
Ответы
Ответ 1
Я думаю, что нашел решение... Подробнее см. здесь: 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, и доступ должен быть общедоступным или защищенным.
Ответ 2
Вы не можете вставить в IEnumerable. Это касается EF так же, как и для ваших клиентов. Однако вам не нужно использовать ICollection; вы можете использовать IList или другие типы записи. Мой совет, чтобы получить лучшее из обоих миров, заключается в том, чтобы подвергать ваши клиенты DTO, а не сущности.
Ответ 3
Вы можете преодолеть это, используя 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>
Надеюсь, это то, что вы искали.