NopCommerce架构分析之(三)EntityFramework数据库初试化及数据操作
系统启动时执行任务:IStartupTask,启动时执行的任务主要是数据库的初始化和加载。
IStartupTask调用IEfDataProvider进行数据库的初始化。
IEfDataProvider,SqlCeDataProvider:获取数据连接工厂,不同类型数据库,连接工厂不同。
接口IStartupTask的实体类EfStartUpTask的实现如下:
publicclassEfStartUpTask:IStartupTask
{
publicvoidExecute()
{
varsettings=EngineContext.Current.Resolve<DataSettings>();
if(settings!=null&&settings.IsValid())
{
varprovider=EngineContext.Current.Resolve<IEfDataProvider>();
if(provider==null)
thrownewNopException("NoEfDataProviderfound");
provider.SetDatabaseInitializer();
}
}
publicintOrder
{
//ensurethatthistaskisrunfirst
get{return-1000;}
}
}
SqlCeInitializer,CreateCeDatabaseIfNotExists初始化数据库。
IDbContext,NopObjectContext系统数据库操作上下文。加载所有数据库映射类:EntityTypeConfiguration<TEntityType>。代码如下:
protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder)
{
//dynamicallyloadallconfiguration
//System.TypeconfigType=typeof(LanguageMap);//anyofyourconfigurationclasseshere
//vartypesToRegister=Assembly.GetAssembly(configType).GetTypes()
vartypesToRegister=Assembly.GetExecutingAssembly().GetTypes()
.Where(type=>!String.IsNullOrEmpty(type.Namespace))
.Where(type=>type.BaseType!=null&&type.BaseType.IsGenericType&&type.BaseType.GetGenericTypeDefinition()==typeof(EntityTypeConfiguration<>));
foreach(vartypeintypesToRegister)
{
dynamicconfigurationInstance=Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
//...ordoitmanuallybelow.Forexample,
//modelBuilder.Configurations.Add(newLanguageMap());
base.OnModelCreating(modelBuilder);
}
此方法是继承自DbContext。并在系统启动时调用,建立数据表与实体的对应关系。
在类型依赖注册类Nop.Web.Framework.DependencyRegistrar中实现数据库工厂的创建、数据库的加载。如下代码:
//datalayer
vardataSettingsManager=newDataSettingsManager();
vardataProviderSettings=dataSettingsManager.LoadSettings();
builder.Register(c=>dataSettingsManager.LoadSettings()).As<DataSettings>();
builder.Register(x=>newEfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency();
builder.Register(x=>(IEfDataProvider)x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency();
builder.Register(x=>(IEfDataProvider)x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IEfDataProvider>().InstancePerDependency();
if(dataProviderSettings!=null&&dataProviderSettings.IsValid())
{
varefDataProviderManager=newEfDataProviderManager(dataSettingsManager.LoadSettings());
vardataProvider=(IEfDataProvider)efDataProviderManager.LoadDataProvider();
dataProvider.InitConnectionFactory();
builder.Register<IDbContext>(c=>newNopObjectContext(dataProviderSettings.DataConnectionString)).InstancePerHttpRequest();
}
else
{
builder.Register<IDbContext>(c=>newNopObjectContext(dataSettingsManager.LoadSettings().DataConnectionString)).InstancePerHttpRequest();
}
builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
接口IEfDataProvider的实体类SqlServerDataProvider的数据库初始化方法如下:
///<summary>
///Setdatabaseinitializer
///</summary>
publicoverridevoidSetDatabaseInitializer()
{
//passsometablenamestoensurethatwehavenopCommerce2.Xinstalled
vartablesToValidate=new[]{"Customer","Discount","Order","Product","ShoppingCartItem"};
//customcommands(storedproedures,indexes)
varcustomCommands=newList<string>();
//usewebHelper.MapPathinsteadofHostingEnvironment.MapPathwhichisnotavailableinunittests
customCommands.AddRange(ParseCommands(HostingEnvironment.MapPath("~/App_Data/SqlServer.Indexes.sql"),false));
//usewebHelper.MapPathinsteadofHostingEnvironment.MapPathwhichisnotavailableinunittests
customCommands.AddRange(ParseCommands(HostingEnvironment.MapPath("~/App_Data/SqlServer.StoredProcedures.sql"),false));
varinitializer=newCreateTablesIfNotExist<NopObjectContext>(tablesToValidate,customCommands.ToArray());
Database.SetInitializer(initializer);
}
另外,EntityFramework本事是ORM框架,通过数据库访问上下文建立与数据库的连接及实体与数据表的对应广西。并通过创建IRepository<T>的泛型实体类来实现对每一种数据的处理,也就是所谓的Dao层。业务逻辑层通过每种实体的数据访问仓库Repository<T>来进行数据库操作。