Линк к сущностям и бизнес-логике

Всякий раз, когда я читаю статью о привязке к сущностям, мне кажется, что я должен встроить свою бизнес-логику в сгенерированные классы сущностей.

Это означает, что «пользователь» бизнес-объектов (контроллер, сервисный уровень и т. д.) должен знать об объекте контекста данных, необходимом для использования linq.

Это также означало бы, что DAL-логика и бизнес-логика будут перепутаны.

Многие примеры Microsoft используют какой-то подход DTO. Я не большой поклонник шаблона DTO.

Итак, должен ли я позволить бизнес-объекту инкапсулировать linq-entity и предоставить доступ к нему с помощью свойств, или я должен придерживаться шаблона DTO?

Каковы ваши предложения?

Спасибо


person Community    schedule 20.07.2009    source источник


Ответы (3)


Модель объекта создает частичные классы. В моем проекте я использую модель сущностей внутри библиотеки классов и добавляю к ней несколько файлов .cs, которые добавляют функциональность к классам сущностей по умолчанию. (В основном это функции, связанные с регистрацией ошибок и сообщений в таблице базы данных и методом импорта/экспорта всех данных в XML.)

Но настоящая бизнес-логика находится во второй библиотеке классов, которая ссылается на эту библиотеку классов сущностей.


Поясним. Сначала я создал модель объекта из базы данных. Он содержит список названий компаний и адресов. Я делаю это, выбирая «Новый проект | Библиотека классов», а затем добавляю модель данных объекта ADO.NET в эту библиотеку. Модель Entity будет связана с моей базой данных SQL Server, импортирует нужные мне таблицы и автоматически создает классы для таблиц, к которым я хочу получить доступ. Затем я добавляю второй файл .cs для каждой таблицы, которую я хочу расширить. Это будет несколько необработанных методов, тесно связанных с базой данных. (В основном методы импорта/экспорта и ведение журнала ошибок.) Это я вызову Entity.Model, который будет скомпилирован в Entity.Model.dll.

Затем я добавляю второй проект, который будет содержать бизнес-логику. Опять же, я использую «Новый проект | Библиотека классов», чтобы создать его и добавить Entity.Model.dll к его ссылкам. Затем я начинаю писать классы, которые преобразуют классы, специфичные для базы данных, в более логические классы. В общем, мне не пришлось бы вносить много изменений, за исключением того, что я буду защищать или скрывать определенные поля и добавлять несколько вычисляемых полей. Бизнес-логика будет раскрывать только те функции, к которым я хочу получить доступ из моего клиентского приложения, и ни один метод больше. Таким образом, если я не позволю клиенту удалять компании, функция «Удалить» в модели объекта не будет доступна на бизнес-уровне. И, может быть, я хочу отправить уведомление, когда компания меняет свой адрес, поэтому я добавлю событие, которое срабатывает при изменении поля адреса компании. (Что будет писать журнал сообщений или что-то еще.) Я назову это business.logic, и он скомпилируется в Business.Logic.dll.

Наконец, я создам клиентское приложение и добавлю ссылку на Business.Logic.dll. (Но НЕ к модели объекта.) Теперь я могу начать писать свое приложение и получать доступ к базе данных через бизнес-уровень. Бизнес-уровень будет выполнять проверки, запускать несколько событий и делать что-либо еще, помимо изменения базы данных через модель объекта. А модель сущностей просто служит для того, чтобы поддерживать простоту отношений с базой данных, позволяя мне «проходить» данные по всем внешним ссылкам в базе данных.

person Wim ten Brink    schedule 20.07.2009
comment
Спасибо за ответ, но как вторая библиотека классов использует модель сущности (посмотрите мой комментарий к предыдущему ответу). - person ; 20.07.2009
comment
Библиотека классов сущностей является общедоступным классом. Он добавляется к ссылкам второго класса и с использованием пространства имен класса сущностей в моем втором классе. Обе библиотеки классов компилируются в сборки .DLL. Я добавлю более подробное объяснение к моему ответу выше. - person Wim ten Brink; 20.07.2009

Я бы не стал редактировать сгенерированные файлы, так как они могут измениться.

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

ayende делает очень хорошее замечание о том, где DAL действительно должен жить

Кроме того, вы должны быть поклонником viewmodels/dtos;)

person Andrew Bullock    schedule 20.07.2009
comment
Итак, вы предлагаете мне создать кучу классов менеджеров без сохранения состояния, которые используют объект запроса (например, примеры Microsoft)? Или мои бизнес-классы должны содержать экземпляр объекта запроса и предоставлять его нижележащему слою? Таким образом, у меня мог бы быть метод сохранения, метод загрузки... для бизнес-объекта. - person ; 20.07.2009
comment
постоянство не имеет ничего общего с бизнес-логикой. Когда вы говорите linq to entites, вы имеете в виду linq для sql, а не linq для объектов? если это так, то я действительно не буду использовать инструмент автоматического генератора, просто отредактирую xml самостоятельно или использую свободный linq2sql. Тогда ваши сущности могут быть почти POCO и могут иметь бизнес-логику вместе с вашими классами обслуживания. имейте в виду, что linq2sql был удален MS, потому что это отстой. - person Andrew Bullock; 20.07.2009
comment
Очевидно, он говорит о linq2entities, а не о linq2sql. Кроме того, linq2sql не был удален, потому что он отстой. Microsoft решила сосредоточиться на Entity Framework и объединить два разных проекта в один. - person Chrisb; 20.07.2009
comment
Под привязкой к сущностям я имею в виду прежнюю структуру сущностей ADO.net. Он сравним с linq to sql, но имеет более продвинутые возможности сопоставления (не 1:1 с db, больше похоже на nHibernate,...). Он должен стать преемником linq to sql. Вы можете сравнить его с nHibernate. Но все же остается вопрос, следует ли мне встраивать свою шинную логику в частичные классы модели сущностей, или мне нужно создать дополнительный слой? И должен ли этот дополнительный уровень быть без состояния (статические методы) или с полным состоянием (как в традиционном ООП)? Спасибо - person ; 20.07.2009
comment
Это вопрос, на который я еще не ответил для себя. Лично я надеюсь, что в структуру будет добавлена ​​возможность использовать схему базы данных. Было бы неплохо иметь возможность использовать его для проверки. На данный момент я иду по маршруту сервисного уровня. - person Chrisb; 20.07.2009

Я предпочитаю оборачивать вызовы классов сущностей в бизнес-классы. (Для краткости назовем его BC.) Каждый BC имеет несколько конструкторов, один или несколько из которых позволяют передавать ему контекст. Это позволяет одному BC вызывать другой BC и загружать связанные данные в том же контексте. Это также упрощает работу с коллекциями BC, которым нужен общий контекст.

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

Я пишу, используя шаблон MVVM. Преимущество этого подхода заключается в том, что до сих пор я мог писать свои модели представления, даже не обращаясь к контексту данных, а только к BC, которые формируют мои модели. Следовательно, если мне нужно изменить мой доступ к данным (заменить инфраструктуру сущности или обновить до версии 4, когда она вышла из бета-версии), мои представления и модели представления будут изолированы от изменений, требуемых в BC.

Не уверен, что это лучший подход, но пока мне нравятся результаты. Чтобы правильно спроектировать BC, требуется настройка, но в итоге я получаю гибкий, расширяемый и удобный в сопровождении набор классов.

person RB Davidson    schedule 20.07.2009
comment
Спасибо за ответ. Вы предоставляете данные как свойства на своем BC или просто предоставляете результаты своих запросов, используя какой-то метод (например, GetCurrentData()). - person ; 20.07.2009
comment
Я раскрываю определенные свойства/поля объектов сущности, к которым мне нужен доступ, и не более того. Если мне не нужно раскрывать поле или свойство объекта сущности за пределами BC, я не создаю для него общедоступное или даже защищенное свойство или метод. Я часто создаю частные свойства/методы, чтобы лучше инкапсулировать внутреннюю логику. - person RB Davidson; 20.07.2009