Потрясающий вопрос.Моя первая рекомендация - думать по шаблонам.С учетом сказанного ...
- Вы в значительной степени прибили преимущества использования POCO.Есть несколько явных преимуществ в отделении ваших бизнес-объектов (объектов POCO) от уровня доступа к данным.Но основная причина, как вы сказали, возможность изменить или изменить слои ниже.Однако, используя POCO, вы по сути следуете подходу Code First (CF).Лично я считаю это Code In Parallel в зависимости от вашего жизненного цикла разработки программного обеспечения.У вас все еще есть все навороты, которые есть у подхода к данным или модели, и некоторые из них, поскольку вы можете расширить DbContext, который является ObjectContext.Я прочитал статью, которую я не могу найти, что CF - это будущее Entity Framework.Наконец, с POCO приятно то, что вы можете включать правила проверки здесь или где-либо еще.Вы также можете предоставить прогнозы.Допустим, у вас есть Дата рождения, но вы также хотите иметь возраст.Теперь это становится легкой задачей, поскольку свойство Age игнорируется при сопоставлении с базой данных.
- Лично я создаю свои собственные бизнес-объекты (POCO) для больших проектов, которые, как правило, живут своей жизнью, где изменения являютсяобраз жизни.Другая мысль - это масштабируемость и ремонтопригодность.Что если в будущем я решу разделить функциональность между приложениями, в которых, как вы упомянули веб-сервисы, функциональность теперь предоставляется из двух разных мест.Если вы инкапсулировали свои бизнес-объекты и DAL в одном и том же разделении блоков кода или масштабируемость теперь стала немного более сложной.Однако рассмотрим проект.Он может быть небольшим с небольшими изменениями в будущем, поэтому не нужно бросать гранату, чтобы убить муху.В какое время данные могут быть первым способом, позволяющим файлу edmx представлять ваши объекты.Так что не женитесь на одной технологии или одной методологии / шаблоне.Делайте то, что имеет смысл для вашего времени и бизнеса.
- Использование заявлений совершенно нормально.На самом деле я недавно был включен, чтобы затем обернуть это в TransactionScope.Если возникает ошибка, откатам присуще.Далее нужно рассмотреть UnitOfWork.Шаблон UnitOfWork инкапсулирует моментальный снимок того, что должно быть выполнено, когда контекст данных является границами, с которыми вы работаете.Для каждого UnitOfWork у вас есть тема, по которой должна выполняться работа.Например, Сотрудник.Таким образом, если вы хотите сохранить информацию о сотруднике, чтобы сделать ее проще, вы должны позвонить в службу BL или хранилище (которое когда-либо).Там вы передаете идентификатор сотрудника, выполняете некоторую работу в этом модуле UnitOfWork, где он либо создается в конструкторе, либо использует инъекции зависимостей (DI или IoC).Простой старт - это StructureMap.Там служба совершает необходимые вызовы в ваш UnitOfWork (DbContext), а затем возвращает управление обратно в восходящий поток (например, UI).
- Лучший способ узнать здесь - это просмотреть код другого пользователя.Я бы начал с некоторых примеров Microsoft.Я бы начал с Nerd Dinner (http://nerddinner.codeplex.com/), затем построил бы это.
Дополнительное чтение:
Использовать шаблон прототипа или нет
http://weblogs.asp.net/manavi/archive/2011/05/17/associations-in-ef-4-1-code-first-part-6-many-valued-associations.aspx
[EDIT] NightHawk457, мне очень жаль, что я не ответил на ваши вопросы. Надеюсь, вы поняли это, но для будущих читателей ...
Чтобы помочьвсе визуализируют, представьте нижеприведенную архитектуру, используя в качестве примера модель домена и репозиторий. Помните, что есть много способов сделать скин для кошки, поэтому возьмите это и сделайте его своим, и не забывайте мой комментарий к гранате выше.
- Уровень данных ( Доступ к данным ): MyDbContext: DbContext, IUnitOfWork, где IUnitWork заключает контракты на операции CRUD.
- Репозиторий данных ( Доступ к данным / бизнес-логика ): MyDomainObjectRepository: IMyDomainObjectRepository, который получает IUnitOfWork классом Factory или внедрением зависимости. Вызывает проверку MyDomainObject для операций CRUD.
- Модель домена ( Бизнес-логика ): MyDomainObject с использованием [Пользовательских] атрибутов проверки.Прочитайте это для плюсов / минусов.
- MVVM / MVC / WCF ( Презентация / Сервисные уровни ): какие дополнительные слои вы выбрали,теперь у вас есть доступ к вашим данным, которые красиво упакованы в меньшие модули, которые самостоятельно инкапсулируют свои функции.Уровень представления (например, ViewModel, Controller, Code-Behind и т. Д.) Может затем получить IMyObjectRepository с помощью класса Factory или путем внедрения зависимостей.
Советы:
- Передача строки подключения в MyDbContext, чтобы можно было повторно использовать MyDbContext.
- MySql плохо работает с системой.Transactions.TransactionScope, пример .Я точно не помню, но MySql этого не поддерживал.Это делает тестирование немного сложным, так как мы создали этот уровень разделения.
- Создайте тестовый проект для каждого слоя и при минимальной общей функциональности / правилах тестирования.
- Каждый объект домена должен расширять базуобъект с идентификатором поля как минимум.Также не используйте ключевые атрибуты здесь.Доменный объект должен описывать не архитектуру, а конкретные данные как единое целое.Даже в Code First этого можно достичь с помощью Fluent API.
- Подумайте об общих принципах при создании MyDbContext.;) Прочтите сообщение Диего .
- В ASP.NET репозитории удобно использовать с ObjectDataSources.
Как видите, существует четкое разделениеролей, где IUnitOfWork и IMyDomainObjectRepository являются интерфейсами, которые предоставляют функциональность вышеперечисленных слоев.И, например, IUnitOfWork может быть NHibernate, Entity Framework, LinqToSql или ADO.NET, где все, что нужно изменить, - это изменение класса фабрики или регистрация внедрения зависимостей.К вашему сведению, я также слышал, что хранилище называется Service Layer.Лично мне нравится, чтобы имя не путали с веб-сервисами.Следующим большим отрывом от этой структуры является реализация области контекста базы данных (IUnitOfWork).Простым примером будет страница ASP.NET, где для каждой страницы есть один и только один IUnitOfWork для каждого репозитория или для этого объема работы.То же самое относится и к ViewModels, Controllers и т. Д. Итак, допустим, вам нужно использовать два репозитория, EmployeeRepository и HRRepository.Затем вы можете поделиться IUnitOfWork между обоими или нет.Чтобы пересечь границы страницы, ViewModel или Controller, мы используем ID для сущностей, где они затем извлекаются из БД, и работа выполняется.В качестве альтернативы вы можете передать DTO через границы и присоединиться к контексту, но затем вы начнете терять разделение слоев.
Чтобы продолжить, классы POCO не должны генерироваться автоматически.Фактически вы можете создавать свои классы сущностей с нуля и выполнять сопоставление в расширенном классе DbContext внутри метода OnModelCreating (DbModelBuilder mb).Начните здесь , затем здесь и обратите внимание на Дополнительные ресурсы, Google Fluent API и прочитайте эту запись Диего.
Что касается проверки, это интересный момент, потому что было бы здорово, если бы все бизнес-правила могли быть проверены в одном месте.Ну, как мы все знаем, это не очень хорошо работает.Итак, вот моя рекомендация: сохранить все проверки уровня данных (т. Е. Требуемые, диапазон, формат и т. Д.) С максимально возможной аннотацией данных в объекте домена и оставить проверку процесса в репозитории с четкими ролями репозитория (т. Е. Если (isEmployee) сделай это, иначе это).Я говорю ясно, что вы не хотите добавлять сотрудника в два разных репозитория, где проверка должна дублироваться.Чтобы вызвать проверку, запустите здесь .Захватите ValidationResults и отправьте в восходящий поток с MyRepositoryValidationException, который содержит коллекцию ошибок валидации (например, требуется Employee), которые могут быть представлены на уровне представления.После всего сказанного не забудьте выполнить проверку на уровне представления.Например, вы не хотите, чтобы посты возвращались, чтобы убедиться, что у сотрудника есть действующий адрес электронной почты.
Просто не забудьте сбалансировать время и усилия со сложностью.Для чего-то простого используйте Data First или Model First с файлом EDMX.Затем положите хранилище поверх того, что также содержит все правила проверки.