一般首次建立数据库时,需要运行建立数据库的相关代码,如Database.SetInitializer<BaseContext>(new BaseInitializer()); 但如果后续进行更改,为了保留数据,一般通过MIGRATION进行,且将建表的相关代码删除或注释了。而CODE FIRST的跨数据库,据此而言也不是仅仅的更改配置了。当然,如果添加CreateDatabaseIfNotExists估计影响不大,但如果是DropCreateDatabaseIfModelChanges或者DropCreateDatabaseAlways,则会丢失相关数据。
一,在models文件夹中,建立相应的model文件
这里注意一点,这里建立的class名,就是数据库里表的名字。
在这里面,可以建立表之间的关系。
这里要说明一点的事,一般情况下,我们会把n:m的形式,变成两个1:n的模式
- //学生信息
- namespace codefirst.Models
- {
- public class Students
- {
- public int ID { get; set; }
- [Required]
- [MaxLength(10)]
- public string stu_Name { get; set; }
- public string stu_Pwd { get; set; }
- public string stu_sex { get; set; }
- public int stu_age { get; set; }
- public virtual ICollection<StuCousers> StuCousers { get; set; }
- }
- }
- //课程信息
- namespace codefirst.Models
- {
- public class Courses
- {
- public int ID { get; set; }
- public string course_Name { get; set; }
- public string course_code { get; set; }
- public virtual ICollection<StuCousers> StuCousers { get; set; }
- }
- }
- //学生课程关联表
- namespace codefirst.Models
- {
- public class StuCousers
- {
- public int ID { get; set; }
- public int StudentID { get; set; }
- public int CourseID { get; set; }
- public virtual Students Student { get; set; }
- public virtual Courses Course { get; set; }
- }
- }
- namespace codefirst.DAL
- {
- public class BaseContext : DbContext
- {
- /// <summary>
- /// 构造函数中的 base("AccountContext") 。
- /// 默认情况下和类名一样,即AccountContext,我们显式的给他指定出来。
- /// </summary>
- public BaseContext()
- : base("BaseContext")
- {
- }
- public DbSet<Students> Students { get; set; }
- public DbSet<Courses> Courses { get; set; }
- public DbSet<StuCousers> StuCousers { get; set; }
- /// <summary>
- /// 指定单数形式的表名
- /// 默认情况下会生成复数形式的表,如SysUsers
- /// </summary>
- /// <param name="modelBuilder"></param>
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
- }
- }
- }
这里面DbSet对应着数据库里表
三,初始化数据库与表
第一次运行程序时新建数据库,插入测试数据; model改变(和database不一致)时删除重建数据库,插入测试数据。
先不用管数据丢失的问题,直接drop and re-create比较方便。
- namespace codefirst.DAL
- {
- public class BaseInitializer : DropCreateDatabaseIfModelChanges<BaseContext>
- {
- protected override void Seed(BaseContext context)
- {
- var stu = new List<Students>
- {
- new Students{stu_Name="小明",stu_Pwd="123456",stu_sex="男"},
- new Students{stu_Name="小芳",stu_Pwd="654321",stu_sex="女"}
- };
- stu.ForEach(s => context.Students.Add(s));
- context.SaveChanges();
- var cou = new List<Courses>
- {
- new Courses{course_Name="语文",course_code="10001"},
- new Courses{course_Name="数学",course_code="10002"}
- };
- cou.ForEach(c => context.Courses.Add(c));
- context.SaveChanges();
- }
- }
- }
四,修改根目录下面的Web.config文件,添加
- <connectionStrings>
- <add name="BaseContext" connectionString="Data Source=.;database=StuAndCourse;uid=sa;pwd=xxxxxxx;AttachDBFilename=|DataDirectory|\StuAndCourse.mdf" providerName="System.Data.SqlClient" />
- </connectionStrings>
这样,会在App_Data文件夹下生成名为StuAndCourse的数据库
五,在Global.asax文件,添加创建语句
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- //添加建表
- Database.SetInitializer<BaseContext>(new BaseInitializer());
- }
- namespace codefirst.Controllers
- public class StudentController : Controller
- {
- BaseContext db = new BaseContext();
- // GET: Student
- public ActionResult Index()
- {
- return View(db.Students.ToList());
- }
- }
- @model IEnumerable<codefirst.Models.Students>
- @{
- Layout = null;
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Index</title>
- </head>
- <body>
- <div>
- <table>
- @foreach (var item in Model)
- {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.stu_Name)
- </td>
- <td>
- @foreach(var sc in item.StuCousers)
- {
- @Html.Label(sc.Course.course_Name)
- }
- </td>
- </tr>
- }
- </table>
- </div>
- </body>
- </html>
好,现在运行程序,你会发现,数据显示出来了,而且数据库也建立成功了。这里为什么要有第六,七步呢,因为你要有一个操作数据库的代码,它才会去建数据库。
下面我们再来看一下,如果我修改了Models中的文件,使得SysUser与数据库中的SysUser表的字段不一样了,这样如果我再运行程序,你会发现数据库被重置了。
这为什么呢,还记得第三步吗,这里就是如果结构不一定,就会删除再生成表。
可是我们在开始的过程中,有一些数据,不希望丢怎么办呢。
工具 -> 库程序包管理器 -> 程序包管理器控制台
运行命令 Enable-Migrations
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded migration '201212090821166_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.
会出现,上面这个错误。不用管它,这时候,你会发现在程序端多出一个文件夹叫Migrations
这里面有一个Configuration.cs文件
打开它,然后修改成如下样子,
public Configuration()
{
AutomaticMigrationsEnabled = true; //这里变成true
ContextKey = "codefirst.DAL.BaseContext";
}
修改完成后,运行
Update-Database -Force这个时候,你再看一下数据库里面的表结构是不是变了,而数据却没有丢呢.
以后再有更改,只要保证Configuration.cs文件中的AutomaticMigrationsEnabled = true;
只运行Update-Database -Force就可以了