EF Codefirst学习系列三:种子数据

Posted 为了暖宝宝的幸福生活而奋斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF Codefirst学习系列三:种子数据相关的知识,希望对你有一定的参考价值。

1、写在前面

  前面写了数据库自动生成,有的朋友可能会发现了,这玩意不好用啊,我辛辛苦苦写了好久的测试数据,自动建库时一下子清了个干干净净,再测试又要辛辛苦苦的重新创建,这不是坑人吗!嗯,你说的很对,是很坑,我也觉得很坑,所以今天咱们来学更好的方法。

2、开搞

  想保留测试数据的话有两种方式可以实现,这里先说说第一种:创建种子数据。

  假设这样一个场景,有一天咱们正在开开心心的撸代码,突然领导过来说:猿猿,先把你手里的活放放,这里有一个学生管理系统比较紧急,先把这个搞搞吧。虽然咱们很不爽被打断,但是本着敬(gong)业(zi)精神,也只能接受了,那么开始做吧。

  学生管理系统嘛,肯定得有学僧啊,于是咱们先建一个学生类Student:

public class Student
    {
        public int SId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public virtual IList<Course> Courses { get; set; }
    }

  学僧每天干啥,当然是上课了,所以再来一个课程类Course:

public class Course
    {
        public int CId { get; set; }
        public string Name { get; set; }
        public int SId { get; set; }
        public Student Student { get; set; }
    }

  好了,就先弄这两个就行了,先把数据库搞起来,配置字符串,数据库初始化设置为DropCreateDatabaseIfModelChanges(有关该类详细介绍及配置请参考第二篇)模式,建立DbContext类,启动。。。。坐等数据库建好~~~然而,伟大的征程总是会有困难出现的,这不困难来了,报错了,信息如下:

Course: EntityType: EntitySet \'Course\' is based on type \'Course\' that has no keys defined.
Student: EntityType: EntitySet \'Student\' is based on type \'Student\' that has no keys defined.

意思呢就是这两个类没有主键,因为一般来说表是应该有主键的,唯一标识,查起来也快,没主键EF不给你干活,算了,它想要咱们就给它呗,还能跟它干起来不成,怎么加呢,两种方式:设置特性重写方法

设置特性即利用命名空间DataAnnotation下的Key特性来告诉EF某个属性是主键,如:

[Key]
public int SId { get; set; }

重写方法即DbContext类中的OnModelCreating方法,如:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().HasKey(s => s.SId);
            modelBuilder.Entity<Course>().HasKey(c => c.CId).HasRequired(c => c.Student).WithMany(s => s.Courses).HasForeignKey(c => c.SId);
            base.OnModelCreating(modelBuilder);
        }

其中,HasKey方法就是设置model主键的。

二者任选其一就行了,OK~障碍排除,继续启动坐等数据库建立,这次没有问题直接成功:

哎哎哎,等等,这就建好库了?不是说好搞什么种子数据的吗,数据呢?别急,一步步来。

  IDatabaseInitializer接口定义了一个Seed约束,作用是创建种子数据的,实现这个接口的类都会有这个方法,咱们就建立一个类继承DropCreateDatabaseAlways重新建库来实现种子数据的创建吧。

public class DbInitializer:DropCreateDatabaseAlways<GGDbContext>
    {
        protected override void Seed(GGDbContext context)
        {
            context.Student.Add(new Student() { Name = "tom",Age=3});
            context.Student.Add(new Student() { Name = "angela", Age = 2 });
            context.Course.Add(new Course() { Name = "挠痒", Student = new Student() { Name = "ben", Age = 12 } });
            context.Course.Add(new Course() { Name = "放屁", Student = new Student() { Name = "jimmy", Age = 6 } });
            base.Seed(context);
        }
    }

然后在Global.asax中将数据库初始化类设置成咱们自定义的类就行了。

Database.SetInitializer(new DbInitializer());

这样创建数据库时就能把上面你添加的数据自动插入到表中用于测试,当然你可以多加点数据。

有了,正是咱们设置的初始化数据。破费!

3、结局

  OK,这一篇到这里先结束吧,本来打算在这篇里将数据迁移也记录下,不过感觉篇幅肯定比较大,我个人看的时候是最怕这种长篇累牍的文章的,学习效率会很低,所以打算在下一篇里单独写数据迁移,也是最重头的部分,敬请期待哦~

 

  

以上是关于EF Codefirst学习系列三:种子数据的主要内容,如果未能解决你的问题,请参考以下文章

EF-CodeFirst-1 玩起来

EF-CodeFirst-1 玩起来

Entity Framework 学习系列 - EF 增删改

EF 增删改

EF CodeFirst系列---FluentApi

EF CodeFirst系列--- FluentApi配置单个实体