Выбираем все плюсы из трех парадигм Entity Framework

Между парадигмами разработки с Entity Framework (Code First, Model First, Database First) я выбрал промежуточную, потому что ни одна меня не устраивала полностью. В Code First меня радуют чистые POCO классы, но не устраивает невозможность моделирования базы. В Database First и Model First мне не нравится генерация EDMX и другого всего лишнего.

Таким образом, я нашел для себя такое решение:

1. Я моделирую схему в любой удобной программе (тут любая внешняя программа моделирования, генерирующая SQL Server-совместимые скрипты генерации базы)

Рис. Смоделированная схема БД.

2. Создаю базу в SQL Management Studio

3. Делаю Reverse Engineering базы в POCO классы (как в Code First) с помощью плагина Entity Framework Power Tools

Рис. Установленный плагин для Reverse Engineer.

Рис. Вот так делается Reverse Engineer базы данных в POCO классы.

Рис. Результат генерации POCO классов на основе базы данных: папочка Models с готовым контекстом, классами объектов и маппинг-классами.

Далее я прикручиваю любой удобный Inversion Of Control Framework к проекту, используя паттерны Repository и Storage, и таким образом получаю гибкую и поддерживаемую структуру. Ниже пример использования Simple Injector в MVC проекте. ModelContainer – это готовый класс, в котором нужно зарегистрировать все свои репозитории (предоставляющие только операции Insert, GetById, Delete, Update для каждого объекта БД) и сервисы, вроде аутентификатора...

namespace Phi.Repository
{
    using System.Web;
    using Microsoft.AspNet.Identity;
    using Phi.Models;
    using SimpleInjector;

    public class ModelContainer
    {
        private static readonly Container _instance;

        static ModelContainer()
        {
            _instance = new Container();

            _instance.Register<IDbContext, phiContext>();
            _instance.RegisterManyForOpenGeneric(
                typeof(IRepository<>),
                new[]
                {
                    typeof(EfRepository<PhiUser>),
                    typeof(EfRepository<Role>),
                    typeof(EfRepository<UserAttribute>),
                    typeof(EfRepository<UserRole>),
                    typeof(EfRepository<UserClaim>),
                    typeof(EfRepository<UserLogin>),
                    typeof(EfRepository<Setting>),
                    …
                });
            _instance.Register<IAuthProvider, AuthProvider>();
            _instance.Register<HttpContextBase>(() => new HttpContextWrapper(HttpContext.Current));
            _instance.Register<IUserStore<PhiUser>, UserStore>();
            _instance.Register<IUserClaimStore<PhiUser>, UserStore>();
            _instance.Register<IUserLoginStore<PhiUser>, UserStore>();
            _instance.Register<IUserRoleStore<PhiUser>, UserStore>();
            _instance.Register<IUserPasswordStore<PhiUser>, UserStore>();

            _instance.Register<IRoleStore<Role>, RoleStore>();

            …
        }

        public static Container Instance
        {
            get
            {
                return _instance;
            }
        }
    }
}

...а затем в методе Application_Start указать Ваш Injector как разруливателя зависимостей:

protected void Application_Start()
{
    …
    var container = ModelContainer.Instance;

    var assem = Assembly.GetExecutingAssembly();
    container.RegisterMvcControllers(assem);
    container.RegisterMvcAttributeFilterProvider();
    container.Verify();

    // Set resolver.
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    …
}

Таким образом, я получил простые POCO классы, описывающие мою модель, но при этом не писал ни строчки кода ручками. Зато, любое изменение в модели данных делается обычным рисованием схемы и генерацией скрипта - опять таки автоматически.

Комментарии

  1. Спасибо за наводку на плагин. Как же меня задолбало руками poco-классы писать:)

    ОтветитьУдалить

Отправить комментарий

Популярные

Кастомизируем ASP.NET Identity 2.0

Делаем себе бесплатный VPN на Amazon EC2