Asp.net Mvc 数据库上下文初始化器

在Asp.net Mvc 和Entity FrameWork程序中,如果数据库不存在,EF默认的行为是新建一个数据库。如果模型类与已有的数据库不匹配的时候,会抛出一个异常。

通过指定数据库上下文对象初始化器,可以执行删除和重新创建数据库,并用种子方法填充数据库。

当Asp.net Mvc 应用程序每一次运行的时候,Entity Framework 能够自动创建(或者删除重新创建)数据库。你能够指定每一次程序运行的时候,或者模型与已有数据库不匹配的时候执行 删除重新创建操作,通过指定Seed 方法,EF能自动的调用Seed方法在你重新创建数据库后自动的填充数据。

注意:在数据迁移中执行种子方法后,会将种子方法中的数据记录还原成种子方法中的记录值,也就是说不能保存在U中I做的的更改。因为每次迁移后执行Update-Database命令更新数据后都要调用种子方法。

而采用初始化器的方式如果模型类没有变化,就不会执行初始化器中的种子方法,所以在UI中更改或删除记录的变化 是保存的。

第一种场景:在开发阶段,模型类需要快速迭代,为了保持生成的数据库与模型类一致,需要删除重新创建数据库,但会导致丢失测试的数据,所以使用EF数据库初始化器并用种子方法自动填充测试数据,以方便测试。

第一步:创建数据库初始化器。

1、创建DropCreateDatabaseAlways<DbContext>数据库初始化器。在 程序每次运行的时候都执行删除、重新创建数据库操作

public class SchoolInitializer:DropCreateDatabaseAlways<SchoolContext>
{

protected override void Seed(SchoolContext context)
{
var students = new List<Student>
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
};

students.ForEach(s => context.Students.Add(s));
context.SaveChanges();

2、创建DropCreateDatabaseIfModelChanges<DbContext>数据库初始化器。当模型发生更改的时候,执行删除、重新创建数据库操作

public class SchoolInitializer:DropCreateDatabaseIfModelChanges<SchoolContext>
{
protected override void Seed(SchoolContext context)
{
var students = new List<Student>
{
new Student {FirstMidName ="张",LastName="三",EnrollmentDate=DateTime.Parse("1979-9-1")}
new Student {FirstMidName ="李",LastName="四",EnrollmentDate=DateTime.Parse("2000-9-1")},
new Student {FirstMidName ="王",LastName="二",EnrollmentDate=DateTime.Parse("1979-9-1")}
new Student {FirstMidName ="陈",LastName="五",EnrollmentDate=DateTime.Parse("2000-9-1")},
};

students.ForEach(s => context.Students.Add(s));
context.SaveChanges();

第2步:在应用程序中指定数据库初始化器。有两种方法

1、在Asp.Net Mvc 应用程序 根目录的 Web.Config 的XML文件中的<EntityFramework>节点中配置

<entityFramework>
  <contexts>
    <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
      <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />   //disableDatabaseInitialization="true".可以关闭初始化器
    </context>
  </contexts>

2、在全局应用程序配置文件Global.asax 中的 Application_Start 方法中通过代码的方式指定。

Database.SetInitializer<SchoolContext>(new SchoolInitializer());

第二种场景:部署阶段 如果需要在部署的产品中存储初始化数据,比如在角色权限系统中的超级管理员用户名、密码信息,以便能够登录,或执行其他一些初始化操作,也需要定义和使用一个 数据库上下文初始化器,只能使用 DropCreateDatabaseIfModelChanges<SchoolContext>

第一步:定义一个数据库初始化器

public class MajorContextInitializer:DropCreateDatabaseIfModelChanges<MajorContext>
{
protected override void Seed(MajorContext context)
{
var themeList = new List<BootstrapTheme>()
{
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Stock" ,ThemeDescription="默认主题。黑色背景导航条,蓝色背景标题", IsActived=true},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Cerulean" ,ThemeDescription="深蓝色背景导航条,浅蓝色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Cosmo" ,ThemeDescription="天蓝色背景导航条,天蓝色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Darkly" ,ThemeDescription="翠绿色背景导航条,蓝黑色背景标题,黑色背景", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Flatly" ,ThemeDescription="翠绿色背景导航条,蓝黑色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Sandstone" ,ThemeDescription="绿色背景导航条,蓝黑色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Spacelab" ,ThemeDescription="深蓝色背景导航条,深蓝色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Superhero" ,ThemeDescription="橘黄色背景导航条,橘黄色背景标题,小号字", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="United" ,ThemeDescription="朱红色背景导航条,橘黄色背景标题", IsActived=false},
new BootstrapTheme { BootstrapThemeID=Guid.NewGuid().ToString(), ThemeName="Yeti" ,ThemeDescription="蓝色背景导航条,蓝色背景标题,小号字", IsActived=false}
};

//这里如果不使用Foreach 语句遍历,也可以使用 themeList.Foreach(s =>context.BootstrapThemes.AddOrUpdate(p =>p.ThemeName,s)) 执行upsert操作,以themeName 主题名称作为区分不同的主题。
foreach (var theme in themeList)
{
var _theme = context.BootstrapThemes.Where(x => x.ThemeName == theme.ThemeName).FirstOrDefault();
if (_theme == null)
{
context.BootstrapThemes.Add(theme);

}

}
context.SaveChanges(); //这里实际上并需要使用context.SaveChages().主要是方便调试,定位错误出在哪里。

//既然使用静态构造函数可以初始化主题,那么也应该可以初始化其它DbSet 实体集成员。
var categoryList = new List<Category>()
{
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="专业动态",CategoryDescription="专业建设进展情况",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=1},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="运行机制",CategoryDescription="制度建设情况",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=2},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="教学队伍",CategoryDescription="专业带头人、师资队伍、团队建设情况",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=3},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="实践条件",CategoryDescription="校内、校外实训基地建设",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=4},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="培养方案",CategoryDescription="人才培养方案",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=5},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="校企合作",CategoryDescription="校企合作情况",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=6},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="社会服务",CategoryDescription="社会服务情况",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=7},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="政策法规",CategoryDescription="高等职业教育制度",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=8},
new Category{ CategoryID=Guid.NewGuid().ToString(), CategoryName="课程体系",CategoryDescription="课程体系构成",NavbarIsShow=true,IndexPageIsShow=true, PriorOrder=9}
};

foreach(var category in categoryList)
{
var _category = context.Categories.Where(x => x.CategoryName == category.CategoryName).FirstOrDefault();
if (_category == null)
{
context.Categories.Add(category);
}

}

context.SaveChanges(); //这里实际上并需要使用context.SaveChages().主要是方便调试,定位错误出在哪里。

//添加一条默认的专业名称记录;
var majorName = new MajorName { MajorNameID = Guid.NewGuid().ToString(), MajorNameText = "数控技术" };
if(context.MajorNames.Count() ==0)
{
context.MajorNames.Add(majorName);

}
context.SaveChanges(); //这里实际上并需要使用context.SaveChages().主要是方便调试,定位错误出在哪里。

base.Seed(context);
}
}

第二步:在数据库上下文对象中中定义一个数据库静态构造函数,在静态构造函数中设定初始化器。则每一次调用数据库上下文对象的时候都要检查数据库中是否存在这些初始值,会降低程序的响应速度。 这种方法不是最佳实践。

public class MajorContext:DbContext
{
public DbSet<Category> Categories { get; set; }

public DbSet<Article> Articles { get; set; }

public DbSet<Course> Courses { get; set; }

public DbSet<Resource> Resources { get; set; }

public DbSet<BootstrapTheme> BootstrapThemes { get; set; }

public DbSet<MajorName> MajorNames { get; set; }

public MajorContext()
: base("MajorContext")
{ }

//静态构造函数。MSDN:静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数
static MajorContext()
{
//设置数据库初始化器,它就在应用程序运行的时候加载。
Database.SetInitializer<MajorContext>(new MajorContextInitializer());
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)  // OnModelCreating 方法重写的目的是指定对应Dbse实体集的表格的名称应该是单数,如果没有此方法,数据库中的表格名称会按惯例为复数的名称,如 Studnets、Courses
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

}

时间: 2024-08-06 14:33:32

Asp.net Mvc 数据库上下文初始化器的相关文章

ASP.NET Core 数据库上下文 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 数据库上下文 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 数据库上下文 上一章节中我们了解了 Entity Framework 并讲述了如何配置它.本章节我们就来学习如何使用它 EF 框架 ( Entity Framework ) 使我们能够使用称为实体 ( Entity) 的公共语言运行时 ( CLR ) 对象查询,插入,更新和删除数据 EF 框架将模型中定义的实体和关系映射到数据库.除此之外,它还具有以下能力: 将

ASP.NET MVC 数据库依赖缓存的实现

当数据库中的信息发生变化的时候,应用程序能够获取变化的通知是缓存依赖得以实现的基础.应用程序可以通过轮询获取数据变化的信息,使用轮询的话也不可能重新查一次后再和以前的数据做比较,如果这样的话如果我一个表里面有1000行数据我要是读100次的话是不是得比较1000 x 100 次,显然这种方法是不可行的,那怎么办呢?大家都学过触发器吧,实现数据库依赖缓存的轮询机制就是通过触发器来实现的. 实现步骤简单分析:     首先创建一个用于记录监控信息的表,表的字段就两个一个是表名,一个是版本号.然后,对

ASP.NET MVC 异常Exception拦截器Fillter

异常信息的处理在程序中非常重要, 在asp.net mvc中提供异常属性拦截器进行对异常信息的处理,异常拦截器也没有什么的,只是写一个类,继承另一个类(System.Web.Mvc.FilterAttribute)和一个接口(System.Web.Mvc.IExceptionFilter),实现接口里面OnException方法. 代码实例: 异常拦截器类: 1 using System; 2 using System.Collections.Generic; 3 using System.Li

asp.net mvc中的拦截器

在ASP.NET MVC中,有三种拦截器:Action拦截器.Result拦截器和Exception拦截器,所谓的拦截器也没有什么的,只是写一个类,继承另一个类和一个接口,顺便实现接口里面的方法而以拉!下面我们一一实现! public class ExceptionFillters : FilterAttribute,IExceptionFilter    {        //发生异常时会执行这段代码        public void OnException(ExceptionContex

ASP.NET MVC的Action拦截器(过滤器)ActionFilter

有时项目要进行客户端请求(action)进行拦截(过滤)验证等业务,可以使用拦截器进行实现,所谓的action拦截器也没有什么的,只是写一个类,继承另一个类(System.Web.Mvc.FilterAttribute)和一个接口(System.Web.Mvc.IActionFilter),至于什么是拦截器这里就不说了,网上很多关于这方面文章. 假如现在有这样的一个需求:某个action需要登录才能进行访问,可以使用action属性拦截器进行拦截进行验证 多余的不说了直接上代码 写一个拦截器类:

ASP.NET MVC使用HTML辅助器实现分页

在mvc中可以利用扩展方法添加HTML辅助器方法实现分页,这样就可以方便的实现分页代码的复用,代码如下 1 public static MvcHtmlString PageLinks(this HtmlHelper html, int curPage, int totalPage, Func<int, string> pageUrl) 2 { 3 StringBuilder result = new StringBuilder(); 4 int start = 1, end = totalPa

MVC中的筛选器

在 ASP.NET MVC 中,控制器将定义一些操作方法,这些操作方法与可能的用户交互(如单击链接或提交窗体)之间通常具有一一对应关系.例如,当用户单击链接时,会将请求路由到指定的控制器,然后调用对应的操作方法. 例如操作完成后你要产生日志.语言筛选.等其他动态操作. 筛选器的由来及用途 有时,您需要在调用操作方法之前或运行操作方法之后执行逻辑. 为了对此提供支持,ASP.NET MVC 提供了筛选器.筛选器是自定义类,可提供用于向控制器操作方法添加操作前行为和操作后行为的声明性和编程性手段.

ASP.NET MVC file download sample

ylbtech- ASP.NET MVC:ASP.NET MVC file download sample 功能描述:ASP.NET MVC file download sample 2,TechnologyAndTheEnvironment(技术与环境) 操作系统: windows 开发语言: C# 开发框架: ASP.NET MVC 数据库: 开发软件: Microsoft Visual Studio 2010  开发技术 ASP.NET MVC 3,DatabaseDesign(数据库设计

《ASP.NET MVC 4 实战》学习笔记 7:Ajax(上)

一.jQuery的Ajax: 1.使用jQuery形成Ajax请求: 1)新建AjaxExamples项目,添加CustomAjax控制器: namespace AjaxExamples.Controllers { public class CustomAjaxController : Controller { public ActionResult Index() { return View(); } public ActionResult PrivacyPolicy() { return P