Стратегии замены устаревшего слоя данных на Entity framework и классы POCO
Мы используем .net C# 4.0, VS 2010, EF 4.1 и устаревший код в этом проекте, над которым мы работаем.
Я работаю над проектом win form, где я принял решение начать использовать entity framework 4.1 для доступа к базе данных ms sql. Кодовая база довольно старая, и у нас есть существующий слой данных, который использует адаптеры данных. Эти адаптеры данных используются повсеместно (в веб-приложениях и приложениях win form) мой план состоит в том, чтобы со временем заменить старый код доступа к БД на EF и избавиться от жесткого связь между уровнями пользовательского интерфейса и уровнем данных.
Таким образом, моя идея состоит в том, чтобы более или менее совместить EF с устаревшим уровнем доступа к данным и постепенно заменить устаревший уровень данных более современным подходом к вещам, использующим EF. Поэтому сейчас нам нужно использовать как EF, так и устаревший код доступа к БД.Что я сделал до сих пор, так это добавил проект, содержащий файл edmx и контекст. Edmx генерируется с использованием первого подхода к базе данных. Я также добавил еще один проект, который содержит классы POCO (by использование ADO.NET генератор сущностей POCO). Я более или менее следовал подходу Джулии Лерман в ее книге "Programming Entity Framework" о том, как разделить модель и сгенерированные классы POCO. Модель базы данных была установлена в течение многих лет, и это не вариант изменения таблицы и отношений, триггеров, хранимых процедур и т. д., Поэтому я в основном застрял с моделью БД, как она есть.
Я читал о шаблоне хранилища и единице работы, и мне вроде как нравятся шаблоны, но я боритесь за их реализацию, когда у меня есть и EF, и устаревший код доступа к БД. Особенно когда у меня нет времени, чтобы заменить весь устаревший код доступа к БД на чистую реализацию EF. В идеальном мире я бы начал все сначала с новой модели данных, но это не вариант здесь.
Является ли хранилище и единица работы паттернов способом, чтобы пойти здесь? Чтобы использовать классы POCO в моем бизнес-уровне, мне иногда нужно использовать как EF, так и наследие код БД для заполнения моих классов POCO. Другими словами, Я иногда могу использовать EF для извлечения части данных, которые мне нужны, и использовать старый уровень доступа к БД для извлечения остальных данных, а затем сопоставить данные с моими классами POCO. Когда я хочу обновить некоторые данные, мне нужно выбрать данные из классов POCO и использовать устаревший код доступа к данным для хранения данных в базе данных. Поэтому мне нужно сопоставить данные, полученные из устаревшего уровня доступа к данным, с моими классами POCO, когда я хочу отобразить данные в пользовательский интерфейс и наоборот, когда я хочу сохранить данные в базе данных.
Чтобы усложнить задачу, мы храним некоторые данные в таблицах, названия которых мы не знаем до выполнения (пожалуйста, не спрашивайте меня, почему: -)). Поэтому на старом уровне доступа к БД нам приходилось создавать SQL-операторы на лету, куда мы вставляли имена таблиц и столбцов на основе информации из других таблиц.
Я также нахожу, что отношения между классами POCO несколько слишком ориентированы на базу данных. Другими словами, Я чувствую, что Мне нужна более упрощенная модель предметной области для работы. Возможно, мне следует создать модель домена, которая соответствует требованиям, а затем использовать классы POCO как " DAO " для заполнения классов модели домена?
Как бы вы реализовали это, используя шаблон репозитория и шаблон единицы работы? (если это путь)
3 ответа:
Генератор классов EDMX + POCO приводит к коду EFv4, а не коду EFv4. 1, но вам не нужно беспокоиться об этих деталях. EFv4. 1 предлагает просто другой API, который делает то же самое (и это только оболочка вокруг EFv4 API).
В зависимости от того, как вы используете наборы данных, вы можете решить некоторые очень сложные проблемы. Наборы данных-это представление шаблона набора изменений. Они знают, какие изменения были внесены в данные, и могут хранить только эти изменения. Сущности EF знают это только в том случае, если они прикрепляется к контексту, который загрузил их из базы данных. После того, как вы работаете с обособленными сущностями, вы должны приложить большие усилия, чтобы сказать EF, что изменилось - особенно при изменении отношений (обособленные сущности являются обычным сценарием в веб-приложениях и веб-службах). Для этих целей EF предлагает другой шаблон, называемый self-tracking entities, но у них есть другие проблемы и ограничения (например, отсутствует ленивая загрузка, вы не можете применить изменения, когда сущность с тот же ключ присоединяется к контексту и т. д.).
EF также не поддерживает некоторые функции, используемые в наборах данных , напримеруникальные ключи ипакетные обновления . Забавно, что новые MS API обычно решают некоторые проблемы предыдущих API, но в то же время предоставляют гораздо меньше возможностей, чем предыдущие API, которые вводят новые проблемы.
Другая проблема может быть с производительностью-EF медленнее, чем прямой доступ к данным с наборами данных и имеют более высокое потребление памяти (и да сообщается о некоторых утечках памяти).
Вы можете забыть об использовании EF для доступа к таблицам, которые вы не знаете во время разработки. EF не допускает никакого динамического поведения. Имена таблиц и тип сервера базы данных фиксируются в сопоставлении. Другая проблема может быть связана с тем, как вы используете триггеры-инструменты ORM не любят триггеры, а EF имеет ограниченные возможности при работе с вычисляемыми значениями базы данных (возможность заполнения значения в базе данных или в приложении есть дизъюнктивный).
Способ заполнения POCOs из наборов данных EF + звучит так, что это будет невозможно при использовании только EF. EF имеет некоторые разрешенные шаблоны отображения, но возможности отображения нескольких таблиц в один класс POCO крайне ограничены и ограничены (если вы хотите, чтобы эти таблицы можно было редактировать). Если вы имеете в виду просто загрузку одной сущности из EF и другой сущности из Data adapter и просто сделать ссылку между ними, вы должны быть в порядке - в этом сценарии репозиторий звучит разумно шаблон, потому что назначение репозитория именно таково: загружать или сохранять данные. Модуль работы также может быть полезен, поскольку вы, скорее всего, захотите повторно использовать одно подключение к базе данных между EF и адаптерами данных, чтобы избежать распределенной транзакции во время сохранения изменений. UoW будет местом, ответственным за обработку этого соединения.
Отображение EF связано с проектированием базы данных - вы можете ввести некоторые объектно-ориентированные модификации, но все же EF тесно зависит от базы данных. Если вы хотите использовать некоторую расширенную модель домена, вам, вероятно, понадобятся отдельные доменные классы, заполненные из EF и наборов данных. Опять же, ответственность за сокрытие этих деталей будет лежать на репозитарии.
Для меня звонят тревожные колокола! Мы пытались сделать что-то подобное некоторое время назад (только с nHibernate не EF4). У нас было несколько проблем с бегом ADO.NET наряду с параллелизмом ORM - базы данных, являющимся большим.
Модель базы данных была установлена для годы, и это не вариант. измените таблицу и отношения, триггеры, сохраненные процедуры и т. д., Так что я в основном застрял с моделью БД, как она есть.
Ага. То же самое! Проблема была в том, что наши хранимые procs содержали много бизнес-логики и не были простыми CRUD procs, поэтому держать ORM обновленным с различными обновлениями, выполняемыми хранимой процедурой, было совсем не просто-принцип единой ответственности-не очень хороший, чтобы сломать!
Мой план состоит в том, чтобы заменить старую базу данных код доступа с помощью EF со временем и получите rid для плотного соединения
между слоями пользовательского интерфейса и данными.Может быть, вы могли бы развязаться без необходимости в ORM - как насчет того, чтобы поставить сервис / фасадный слой перед вашим слоем пользовательского интерфейса для координации всех взаимодействий с нижележащим доменом и скрытия его от пользовательского интерфейса.
Если ваша база данных является "королем", а ваше приложение сильно зависит от данных, я думаю, что вы всегда будете вести тяжелую битву, реализуя упомянутые вами шаблоны.
Объятия ado.net для этого проекта-используйте шаблоны EF4 и DDD на вашем следующем зеленом поле proj:)
Из того, как много мы реализовали, я узнал следующие вещи.
С объектами POCO и Self Tracking трудно иметь дело, так как если у вас нет легкого понимания того, что происходит внутри, будет много неожиданного поведения, которое, возможно, хорошо работало в вашем предыдущем проекте.
- изменить шаблон непросто, до сих пор мы управляли простой CRUD без единицы работы и шаблона карты идентичности. Теперь много устаревшего кода, который мы писали в прошлом, не делает рассмотрите эти новые паттерны, и логика не будет работать правильно.
- в нашем предыдущем коде мы просто использовали транзакции и один оператор insert / update / delete, который был непосредственно отправлен в базу данных, предполагая, что транзакции на стороне сервера будут заботиться обо всех операциях.
- в таких условиях мы все время имели дело непосредственно с идентификаторами, новые сгенерированные идентификаторы были сразу доступны после одного оператора insert, однако это не относится к EF.
- в EF мы не являемся имея дело с идентификаторами, мы имеем дело с навигационными свойствами, что является огромным изменением по сравнению с предыдущими ADO.NET методы программирования.
Из нашего опыта мы выяснили, что только замена EF более ранним кодом доступа к данным приведет к хаосу. Но услуги EF + RIA предлагают вам совершенно новое решение, где вы, вероятно, получите все, что вам нужно, и ваш пользовательский интерфейс будет очень легко привязан к нему. Так что если вы задумываетесь о полной переписке с использованием UI + RIA Services + EF, то стоит, потому что много зависимость в управлении запросами уменьшается автоматически. Вы будете фокусироваться только на бизнес-логике, но это большое решение, и количество человеко-часов, необходимых для полного переписывания или просто замены EF, почти такое же.- Итак, мы пошли по пути UI + RIA Services + EF и начали заменять один модуль на другой. В основном EF будет легко сосуществовать с вашей существующей инфраструктурой, так что вреда не будет.