2010-09-09 2 views
6

У меня возникли проблемы с попыткой применить DDD с EF4 (в контексте ASP MVC2). Ваш совет будет очень благодарен.Как вы справляетесь с DDD и EF4

Прежде всего, я начал использовать POCO, потому что зависимость от ObjectContext была не очень удобной во многих ситуациях.

Переход к POCO решил некоторые проблемы, но опыт не в том, к чему я привык с NHibernate.

Я хотел бы знать, можно ли использовать конструктор и создавать не только объекты, но и объекты Value (ComplexType?). Если я имею в виду Value Object - это класс с одним ctor без каких-либо заданных свойств (требуется модификация T4?).

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

Я не знаю, как создать несколько репозиториев с одним edmx. На данный момент я использую частичные классы для группировки методов для каждого агрегата. На самом деле каждая группа является хранилищем.

Последний вопрос: о IQueryable. Должен ли он быть выставлен вне репозитория? Если я ссылаюсь на книгу, то репозиторий должен быть единицей исполнения и не должен выставлять что-то вроде IQueryable. Как вы думаете ?

Благодарим за помощь.

Томас

+1

Что касается вопроса IQueryable, см. Это: http://stackoverflow.com/questions/1699607/asp-mvc-repository-that-reflects-iqueryable-but-not-linq-to-sql-ddd-howtoto -ques/1699756 # 1699756 –

ответ

0

Прошло некоторое время с тех пор, как я задал этот вопрос и имел возможность сделать это самостоятельно.

Я не думаю, что это хорошая практика, чтобы разоблачить IQueryable вообще вне слоя DAL. Это приносит больше проблем, которые он решает. Я говорю о больших приложениях MVC. Прежде всего, реорганизация сложнее, многие разработчики пользовательских экземпляров IQueryable из представлений и после борьбы с тем, что при разрешении IQueryable соединение уже было установлено. Проблемы с производительностью, потому что вся база данных часто запрашивается для заданного набора результатов и так далее.

Я скорее выставил Ienumerable из своих репозиториев и поверьте мне, это избавляет меня от многих неприятностей.

4

Это хорошо использовать Pocos, но учтите, что EntityObject не требует ObjectContext.

Да, сложные типы - это объекты ценности, и да, их можно сгенерировать в дизайнере. Выберите несколько свойств объекта, щелкните правой кнопкой мыши и выберите рефакторинг в сложный тип.

Я настоятельно рекомендую размещать бизнес-методы в своих типах, а не на сущностях. «Анемические» типы могут быть проблемой, если вы должны их поддерживать, но когда они кодируются, они вряд ли являются проблемой обслуживания. Создание бизнес-логики отдельно от типов сущностей позволяет вашим бизнес-правилам и вашей модели данных развиваться независимо. Да, вы должны использовать частичные классы, если вы должны смешивать эти проблемы, но я не считаю, что разделение вашей модели и ваших правил - это плохо.

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

+0

Спасибо за ваш ответ. Обобщение Я ставил очевидные поведенческие методы для сущностей. Когда это не очевидно, я создаю для этого сервис. Как вы решаете этот вопрос? Если хранилища предоставляют IQueryable, поэтому нет никакой гарантии, что он будет удален в любое время или если он будет удален, будет проблема при преобразовании Iqueryable в List или Enumarable, потому что соединение будет уже закрыто. –

+0

Что касается утилизационных подключений, то публичное лицо моих доменных служб является единицей рабочего объекта. Единица работы реализует IDisposable. Единица работы хранит личную ссылку на экземпляр объекта ObjectContext, который передается репозиториям через инъекцию конструктора. В моем случае блок работы потребляется контроллерами ASP.NET MVC, которые сами по себе не расположены до тех пор, пока не отобразятся представления и т. Д. Таким образом, удаление всего в правильное время вполне естественно; Я никогда не должен об этом думать. –

+0

Что касается того, где размещать бизнес-методы, я нахожу более естественным поместить все в сервисы домена, а не в службы домена и другие в разных местах. Это особенно важно при использовании служб данных, таких как службы данных ADO.NET/Astoria. –

1

Я думаю, что это нормально, чтобы открыть IQueryable вне репозитория, только потому, что это не может быть излишне ограничительным. Если вы публикуете только данные с помощью таких методов, как GetPeopleByBirthday и GetPeopleByLastName, что происходит, когда кто-то отправляется на поиски человека по фамилии и день рождения? Вы тянете всех людей с фамилией «Смит» и выполняете линейный поиск нужного вам дня рождения, или вы создаете новый метод GetPeopleByBirthdayAndLastName? Как насчет бедного несчастного человека, который должен реализовать форму QBE?

Назад, когда единственным способом сделать специальные запросы к домену было создание SQL, единственный способ сохранить себя в безопасности - предлагать только определенные методы для извлечения и изменения данных. Теперь, когда у нас есть LINQ, нет никаких оснований держать наручники на. Любой может отправить запрос, и вы можете безопасно выполнить его без забот.

Конечно, вы можете быть обеспокоены тем, что пользователь может просматривать другие данные, но это легко смягчить, поскольку вы можете ограничить данные, которые вы выдаете. Например:

public IQueryable<Content> Content 
{ 
    get { return Content.Where(c => c.UserId == this.UserId); } 
} 

Это позволит убедиться, что только Content строки, которые пользователь может получить те, которые имеют свою UserId.

Если ваша проблема связана с нагрузкой на базу данных, вы можете делать такие вещи, как проверять выражения запросов для сканирования таблиц (доступ к таблицам без предложений Where или без индексированных столбцов в предложении Where). Конечно, это нетривиально, и я бы не рекомендовал его.