EF-CodeFirst实现过程+数据库迁移

简介: 系列文章:EF-ModelFirst实现过程+数据库迁移     http://www.jianshu.com/p/2a53f318144dEF-DBFirst实现过程    http://www.jianshu.com/p/eb84ec814926建议学习路径 DBFirst->ModelFirst->CodeFirst思路:通过代码编写实体和关联,编写上下文,根据实体和关联生成数据库。

系列文章:

EF-ModelFirst实现过程+数据库迁移     http://www.jianshu.com/p/2a53f318144d
EF-DBFirst实现过程    http://www.jianshu.com/p/eb84ec814926
建议学习路径 DBFirst->ModelFirst->CodeFirst

思路:通过代码编写实体和关联,编写上下文,根据实体和关联生成数据库。

EF-CodeFirst的优点

EF-CodeFirst相对于EF-ModelFirst和EF-DBFirst的有点在于,CodeFirst在数据库已经设计完成之后,能够较方便得再次对数据库进行更改(数据库迁移技术)。

关联

1.Database First是基于已存在的数据库,利用某些工具(如VS提供的EF设计器)创建实体类,数据库对象与实体类的匹配关系等,你也可以手动修改这些自动生成的代码及匹配文件。也就是从一个数据库开始,然后生成实体框架和相应代码。
    2.Model First 是先利用某些工具(如VS的EF设计器)设计出可视化的实体数据模型及他们之间的关系,然后再根据这些实体、关系去生成数据库对象及相关代码文件。
    3.Code First 这种方式需要先写一些代码,如实体对象,数据关系等,然后根据已有的代码描述,自动创建数据对象。但其实这种方法与Model First是非常类似的。我们自己写的代码,其实就是用代码表示实体模型,而Model First是用可视化的方式描述了实体模型。

EF-CodeFirst的具体实现过程(以17-3-2课后作业为对象分析)

Step1:按需求新建若干实体Entity

BaseEntity基类


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
    public class BaseEntity
    {
        public BaseEntity()
        {
            CreateTime = DateTime.Now;
            UpdateTime = DateTime.Now;
        }
        /// <summary>
        /// 创建ID
        /// </summary>
        public int ID { get; set; }
        /// <summary>
        /// 创建人
        /// </summary>
        public string CreateBy { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }
        /// <summary>
        /// 更新人
        /// </summary>
        public string UpdateBy { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdateTime { get; set; }
    }
}

Classes班级实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
   public class Classes:BaseEntity
    {
        /// <summary>
        /// 班级编号
        /// </summary>
        public int ClassNO { get; set; }
        /// <summary>
        /// 班级名称
        /// </summary>
        public string ClassName { get; set; }
        /// <summary>
        /// 班主任ID
        /// </summary>
        public int MentorID { get; set; }
        /// <summary>
        /// 班主任名称
        /// </summary>
        public virtual string MentorName { get; set; }
        /// <summary>
        /// 一个班级有多名学生
        /// </summary>
       public virtual List<Student> students { get; set; }
    }
}
Course课程实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
    public class Course:BaseEntity
    {
        /// <summary>
        /// 课程编号
        /// </summary>
        public int CourseNO { get; set; }
        /// <summary>
        /// 课程名称
        /// </summary>
        public string CourseName { get; set; }
        /// <summary>
        /// 一个课程有多名学生
        /// </summary>
        public virtual List<Student> students { get; set; }
        /// <summary>
        /// 一门课程有多个教师
        /// </summary>
        public virtual List<Teacher> Teachers { get; set; }
    }
}

学校School实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
    public class School : BaseEntity
    {
        /// <summary>
        /// 学校编号
        /// </summary>
        public int SchoolNO { get; set; }
        /// <summary>
        /// 学校名称
        /// </summary>
        public string SchoolName { get; set; }
        /// <summary>
        /// 校长ID
        /// </summary>
        public int HeadmasterID { get; set; }
        /// <summary>
        /// 校长名称
        /// </summary>
        public string HeadmasterName { get; set; }
        /// <summary>
        /// 学校地址
        /// </summary>
        public string Address_new { get; set; }
    }
}

学生Student实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
    public class Student:BaseEntity
    {
        /// <summary>
        /// 学生编号
        /// </summary>
        public int StudentNO { get; set; }
        /// <summary>
        /// 学生名称
        /// </summary>
        public string StudentName { get; set; }
        /// <summary>
        /// 一个学生属于一个班级名称
        /// </summary>
        public virtual Classes ClassName { get; set; }
        /// <summary>
        /// 一个学生有多门课程
        /// </summary>
        public virtual List<Course> Courses { get; set; }
    }
}


教师Teacher实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF_CodeFirst_17_3_2.Model
{
    public class Teacher:BaseEntity
    {
        /// <summary>
        /// 教师编号
        /// </summary>
        public int TeacherNO { get; set; }
        /// <summary>
        /// 教师名称
        /// </summary>
        public string TeacherName { get; set; }
        /// <summary>
        /// 一个教师有多门课程
        /// </summary>
        public virtual List<Course> Courses { get; set; }
    }
}


Step2:建立各个实体之间的关联

比如 1 对 *,* 对 *等。

在代码上体现为:比如学生与班级的关系是:* 对 1。
则在实体Student内,存在一个班级对象。
即: /// <summary>
        /// 一个学生属于一个班级名称
        /// </summary>
        public virtual Classes ClassName { get; set; }
而在Classes实体内,存在多个学生,即存在多个学生对象,所以我们用Lisk集合来保存这些对象。

即: /// 一个班级有多名学生
        /// </summary>
       public virtual List<Student> students { get; set; }

注意设置virtual属性。

Step3:在项目中引用EntityFramework

在项目中引用EntityFramework的两种方式:

1.通过 工具 > Nuget包管理器 > 管理解决方案的Nuget程序包,搜索EntityFramework在进行安装就行。

2.通过 工具 > Nuget包管理器 > 程序包管理控制台,输入“Install-Package EntityFramework”,也能自动完成EntityFramework的安装。

注意:不能通过复制EntityFramework的dll文件到项目文件夹下再进行引用。

Step4:配置App.config

<connectionStrings>
    <add name="DBConn" connectionString="Data Source=你的服务器地址; Connection Timeout=60;Initial Catalog=新的数据库名;Integrated Security=False;User ID=sa;Password=YourPassword;multipleactiveresultsets=True;" providerName="System.Data.SqlClient" />
  </connectionStrings>

Step5:编写上下文

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

using EF_CodeFirst_17_3_2.Model;
namespace EF_CodeFirst_17_3_2.EF
{
    public class CodeFirstDBContext : DbContext
    {
        public CodeFirstDBContext() : base("name=DBConn")
        {
            this.Configuration.LazyLoadingEnabled = true;
        }
        static CodeFirstDBContext()
        {
            //一:数据库不存在时重新创建数据库[默认]
            Database.SetInitializer(new CreateDatabaseIfNotExists<CodeFirstDBContext>());
            //二:每次启动应用程序时创建数据库
            //Database.SetInitializer<testContext>(new DropCreateDatabaseAlways<SpreadtrumPMMContext>());
            //三:策略三:模型更改时重新创建数据库
            //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<CodeFirstDBContext>());
            //策略四:从不创建数据库
            //Database.SetInitializer<CodeFirstDBContext>(null);
        }
        public virtual DbSet<Classes> Classes { get; set; }
        public virtual DbSet<Course> Course { get; set; }
        public virtual DbSet<School> School { get; set; }
        public virtual DbSet<Student> Student { get; set; }
        public virtual DbSet<Teacher> Teacher { get; set; }
    }
}

到这里通过EF-CodeFirst构建的项目差不多完成了,运行之后数据库应该会新建一个你在App.config中配置的数据库以及所有的实体对应的表,以及中间表( * 对 * 关系会生成中间表 )。如果没有可能需要向数据库的某个表添加一条数据之后才会出来。

主程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using EF_CodeFirst_17_3_2.EF;
using EF_CodeFirst_17_3_2.Model;
namespace EF_CodeFirst_17_3_2
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 添加学校信息
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    School Ecjtu = new School();
            //    Ecjtu.SchoolName = "华东交通大学";
            //    Ecjtu.SchoolNO = 1;
            //    Ecjtu.CreateBy = "Fnatic";
            //    Ecjtu.HeadmasterID = 1;
            //    Ecjtu.HeadmasterName = "罗玉峰";
            //    Ecjtu.UpdateBy = "Fanatic";
            //    dbContext.School.Add(Ecjtu);
            //    dbContext.SaveChanges();
            //}
            #endregion

            #region 添加课程信息
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    Course English = new Course();
            //    English.CourseName = "英语";
            //    English.CourseNO = 1;
            //    English.CreateBy = "Fnatic";
            //    English.UpdateBy = "Fanatic";

            //    Course Math = new Course();
            //    Math.CourseName = "数学";
            //    Math.CourseNO = 2;
            //    Math.CreateBy = "Fnatic";
            //    Math.UpdateBy = "Fanatic";

            //    dbContext.Course.Add(English);
            //    dbContext.Course.Add(Math);
            //    dbContext.SaveChanges();
            //}
            #endregion

            #region 添加班级信息
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    Classes classA = new Classes();
            //    classA.ClassName = "微创班";
            //    classA.ClassNO = 1;
            //    classA.CreateBy = "Fnatic";
            //    classA.MentorID = 1;
            //    classA.MentorName = "Mentor_A";
            //    classA.UpdateBy = "Fanatic";

            //    Classes classB = new Classes();
            //    classB.ClassName = "卓越班";
            //    classB.ClassNO = 2;
            //    classB.CreateBy = "Fnatic";
            //    classB.MentorID = 2;
            //    classB.MentorName = "Mentor_B";
            //    classB.UpdateBy = "Fanatic";
            //    dbContext.Classes.Add(classA);
            //    dbContext.Classes.Add(classB);
            //    dbContext.SaveChanges();
            //}
            #endregion

            #region 添加教师信息
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    Teacher T_A = new Teacher();
            //    T_A.CreateBy = "Fnatic";
            //    T_A.TeacherName = "Teacher_A";
            //    T_A.UpdateBy = "Fanatic";
            //    T_A.TeacherNO = 1;
            //    dbContext.Teacher.Add(T_A);
            //    dbContext.SaveChanges();
            //}
            #endregion

            //Q:是向学生信息添加班级信息还是向班级信息添加学生信息
            #region 添加学生信息并加入班级
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    for (int i = 1; i <= 32; i++)
            //    {
            //        Student stu = new Student();
            //        stu.CreateBy = "Fnatic";
            //        stu.StudentName = "Student" + "_" + i;
            //        stu.StudentNO = i;
            //        stu.UpdateBy = "Fanatic";
            //        //获取班级
            //        Classes classes = dbContext.Classes.FirstOrDefault(u => u.ID == 1);
            //        stu.ClassName = classes;
            //        dbContext.Student.Add(stu);
            //        dbContext.SaveChanges();
            //    }
            //}
            #endregion

            #region 教师教授课程的设置
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    Teacher teacher = dbContext.Teacher.FirstOrDefault(u => u.ID == 1);
            //    Course courseA = dbContext.Course.FirstOrDefault(u => u.ID == 1);
            //    Course courseB=dbContext.Course.FirstOrDefault(u => u.ID == 2);
            //    List<Course> course = new List<Course>();
            //    course.Add(courseA);
            //    course.Add(courseB);
            //    teacher.Courses = course;
            //    dbContext.SaveChanges();
            //}
            #endregion

            #region 学生选课
            //using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            //{
            //    Course courseA = dbContext.Course.FirstOrDefault(u => u.CourseNO == 1);
            //    List<Course> course = new List<Course>();
            //    course.Add(courseA);
            //    for (int i = 1; i <= 32; i++)
            //    {
            //        Student student = dbContext.Student.FirstOrDefault(u => u.StudentNO == i);
            //        student.Courses = course;

            //    }
            //    dbContext.SaveChanges();
            //}
            #endregion

            #region 添加学校地址之后再次添加学校信息
            using (CodeFirstDBContext dbContext = new CodeFirstDBContext())
            {
                //School Caida = new School();
                //Caida.CreateBy = "Fnatic";
                //Caida.HeadmasterID = 2;
                //Caida.HeadmasterName="王乔";
                //Caida.SchoolName = "江西财经大学";
                //Caida.SchoolNO = 2;
                //Caida.UpdateBy = "Fanatic";
                //Caida.Address_new = "蛟桥镇";
                //dbContext.School.Add(Caida);

                School Ecjtu = dbContext.School.FirstOrDefault(u => u.SchoolNO == 1);
                Ecjtu.Address_new = "江西省南昌市昌北双港东大街808号";
                dbContext.SaveChanges();
            }
            #endregion
        }
    }
}

实体Entity做了更改的时候要做数据库迁移:

enable-Migrations -Force
Add-Migration demo
最后再次执行:Update-Database -Force

数据库会自动生成dbo.__MigrationHistory表来记录更新记录。
在项目下面也会自动生成Migrations文件夹,包括每一次的更新记录,以及Configuration。

关于项目内命名空间的问题:

1. 对于在项目根目录下:命名空间为项目名

img_9987a314bff99d35c0acfc39b16c8407.png
   
img_a713f537c7b1198ea8de182e1a5e911b.png

2. 但是如果在项目下面新建了文件夹,则命名空间为“项目名.文件夹名”

img_ff3b29db684f23c1bef05ab54e76c4bf.png
 

所以在引用不用命名空间下的资源的时候需要首先引用命名空间。


更新:

时间:2017-03-17

codefirst在做数据库迁移的可能出现的错误:



欢迎指正O(∩_∩)O~

目录
相关文章
|
14天前
|
弹性计算 关系型数据库 数据库
自建数据库迁移到云数据库实操
本课程详细介绍了自建数据库迁移到阿里云RDS的实操步骤。主要内容包括:创建实例资源、安全设置、配置自建的MySQL数据库、数据库的迁移、从自建数据库切换到RDS以及清理资源。通过这些步骤,学员可以掌握如何将自建数据库安全、高效地迁移到云端,并确保应用的正常运行。
88 26
|
6天前
|
弹性计算 关系型数据库 数据库
从自建到云端,数据库迁移全攻略
本文详细介绍了将自建数据库迁移至阿里云RDS的全过程,涵盖WordPress网站安装、数据库迁移配置及验证等步骤。通过DTS数据传输服务,实现库表结构、全量和增量数据的无缝迁移,确保业务连续性和数据一致性。方案具备零成本维护、高可用性(最高99.99%)、性能优化及全面的数据安全保障等核心优势。此外,提供了详细的图文教程,帮助用户快速上手并完成迁移操作,确保业务稳定运行。点击文末“阅读原文”了解更多详情及参与活动赢取精美礼品。
|
5月前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
|
30天前
|
弹性计算 安全 关系型数据库
活动实践 | 自建数据库迁移到云数据库
通过阿里云RDS,用户可获得稳定、安全的企业级数据库服务,无需担心数据库管理与维护。该方案使用RDS确保数据库的可靠性、可用性和安全性,结合ECS和DTS服务,实现自建数据库平滑迁移到云端,支持WordPress等应用的快速部署与运行。通过一键部署模板,用户能迅速搭建ECS和RDS实例,完成数据迁移及应用上线,显著提升业务灵活性和效率。
|
14天前
|
运维 关系型数据库 MySQL
自建数据库迁移到云数据库RDS
本次课程由阿里云数据库团队的凡珂分享,主题为自建数据库迁移至云数据库RDS MySQL版。课程分为四部分:1) 传统数据库部署方案及痛点;2) 选择云数据库RDS MySQL的原因;3) 数据库迁移方案和产品选型;4) 线上活动与权益。通过对比自建数据库的局限性,介绍了RDS MySQL在可靠性、安全性、性价比等方面的优势,并详细讲解了使用DTS(数据传输服务)进行平滑迁移的步骤。此外,还提供了多种优惠活动信息,帮助用户降低成本并享受云数据库带来的便利。
|
5月前
|
关系型数据库 MySQL 数据库
|
5月前
|
关系型数据库 MySQL 数据库
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
|
29天前
|
安全 关系型数据库 MySQL
体验自建数据库迁移到云数据库RDS,领取桌面置物架!
「技术解决方案【Cloud Up 挑战赛】」正式开启!本方案旨在帮助用户将自建数据库平滑迁移至阿里云RDS MySQL,享受稳定、高效、安全的数据库服务,助力业务快速发展。完成指定任务即可赢取桌面置物架等奖励,限量供应,先到先得。活动时间:2024年12月3日至12月31日16点。
|
3月前
|
算法 大数据 数据库
云计算与大数据平台的数据库迁移与同步
本文详细介绍了云计算与大数据平台的数据库迁移与同步的核心概念、算法原理、具体操作步骤、数学模型公式、代码实例及未来发展趋势与挑战。涵盖全量与增量迁移、一致性与异步复制等内容,旨在帮助读者全面了解并应对相关技术挑战。
60 3
|
6月前
|
SQL Java 数据库
使用Spring Boot和Flyway进行数据库迁移
使用Spring Boot和Flyway进行数据库迁移