Выбираем все плюсы из трех парадигм 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 классы, описывающие мою модель, но при этом не писал ни строчки кода ручками. Зато, любое изменение в модели данных делается обычным рисованием схемы и генерацией скрипта - опять таки автоматически.
Спасибо за наводку на плагин. Как же меня задолбало руками poco-классы писать:)
ОтветитьУдалить