codefirst数据迁移技术,在保留数据库数据下实现对模型的修改并映射到数据库
一前言
这是我的处女作,写的不好的地方还望指出共同讨论。EF的数据访问方式有三种DbFirst,ModelFirst,还有本文要提到的CodeFirst 三者都是以ORM的方式建立。本人之前学习的.net webform学的不能算精通但也还不错,不过在接触了.net mvc和一般处理程序之后才知道原来以前学的都是皮毛傻瓜式的拖控件,封装的极其好不需要知道任何原理和扩展。我想这也是为什么.net门槛底,java门槛相对高的原因。因为你并不需要知道什么是管道模型,事件响应过程,过滤器机制,线程和IIS,反射机制,路由机制,asp.net事件驱动的内幕。所以我觉得要深入学习.net得先了解一般处理程序,再学习.net mvc和.net core
学习软件技术真的要有耐心和毅力,一天到晚坐在电脑面前耐得住寂寞。还有切忌埋头苦干,靠自己一个人摸索是很费时费力,请教,逛论坛,看demo都是高效的办法,好了不多说了就吹一会牛。
二.NET MVC数据访问之CodeFirst
-
创建实体模型
记得引用下面两个命名空间,导航属性加virtual方便延迟加载默认同名的做外键,否则制定外键特性,导航属性制定了表与表之间的对应关系。顺便提醒一句用ModelFirst开发掉入的坑:建立好edmx模型后,点击生成数据库,执行edmx.sql代码。如果要修改模型添加属性,直接改模型,点击生成数据库,但千万不能执行edmx.sql代码,否则原数据会被清空,要手动到数据库修改表定义。
1 using System.ComponentModel.DataAnnotations; 2 using System.ComponentModel.DataAnnotations.Schema; 3 4 namespace Model 5 { 6 ///<summary> 7 ///用户表 8 ///</summary> 9 [Table("Users")] 10 public partial class Users 11 { 12 ///<summary> 13 ///用户id 14 ///</summary> 15 [Key] 16 public int UserId { get; set; } 17 ///<summary> 18 ///用户姓名 19 ///</summary> 20 [Required] 21 public string UserName { get; set; } 22 ///<summary> 23 ///用户密码 24 ///</summary> 25 [Required] 26 public string UserPassward { get; set; } 27 ///<summary> 28 ///用户生日 29 ///</summary> 30 [Required] 31 public DateTime Birthday { get; set; } 32 ///<summary> 33 ///用户住址 34 ///</summary> 35 [Required] 36 public string UserAddress { get; set; } 37 //导航属性 38 public virtual ICollection<Orders> Order { get; set; }
2.创建上下文类
dbcontext(实体数据模型与数据库的桥梁),新建一个继承自Dbcontext上下文的类,连接字符串和web.config里的连接字符串对应。
1 using System.Data.Entity; 2 3 namespace Model 4 { 5 public class YunanEntities:DbContext 6 { 7 //连接字符串 8 public YunanEntities():base("name=YunanEntities") 9 { 10 11 } 12 static YunanEntities() 13 { 14 //初始数据库植入种子 15 Database.SetInitializer<YunanEntities>(new SeedingDataInitializer() ); 16 } 17 public virtual DbSet<Users> Users { get; set; } 18 19 //级联删除定义 20 protected override void OnModelCreating(DbModelBuilder modelBuilder) 21 { 22 modelBuilder.Entity<Users>().HasMany(u => u.Order).WithRequired(u => u.user).HasForeignKey(u => u.UserId).WillCascadeOnDelete(false); 23 } 24 //数据库种子的初始化,这里定义了每次模型的修改都会删除并建立新的数据库种子 25 public class SeedingDataInitializer :DropCreateDatabaseIfModelChanges<YunanEntities> 26 { 27 protected override void Seed(YunanEntities context) 28 { 29 var User = new Users() 30 { 31 UserName = "乔木志", 32 UserPassward = "931798", 33 Birthday = DateTime.Now, 34 UserAddress = "xxxx", 35 }; 36 context.Users.Add(User); 37 base.Seed(context); 38 } 39 } 40 }
3.配置web.config的连接字符串
<connectionStrings> <add name="YunanEntities" connectionString="Data Source=.;Initial Catalog=Yunan;Integrated Security=SSPI; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> </connectionStrings>
三数据迁移
开始建立的实体模型可能并不是那么完善,或者需求变动要对实体模型和数据库表的定义更改,那怎么办呢,实体模型还好办,直接修改,或使用Metadata扩展,问题来了怎么在保留原有数据库数据的基础上修改表的定义并映射呢:
-
初始化数据迁移,选择项目的上下文目标类
A.打开程序包管理控制台
B.控制台默认项目是你实体模型所在项目
C.完成数据迁移初始化后,之后的迁移就直接从第三步开始
在控制台输入 enable-migrations -ContextTypeName Model.xxxx(Model是你实体和上下文对象所在的项目名称本例是在Model类库项目中,xxx是对应的Dbcontext上下文对象名称)
2.首次初始创建一个migration文件夹包含数据库的schema,包含一个带时间戳的迁移记录表的修改定义都在这里,还包含一个configuration类,其中AutomaticMigrationsEnabled定义了是否开启自动迁移最好为false,我试过了这种自动迁移并不能保留数据库数据的基础上迁移,还得自己写迁移方法网上有很多demo
3.添加迁移,执行后会生成一个新的带时间戳的迁移记录,initial是迁移的文件名称可以随便命名。
输入命令 add-migration initial(这个名字是随便取的生成的迁移文件名称就是这个了)
4.更新数据库,到这步就完成了一次迁移
输入命令 update database 并执行等待完成
四.有说错的地方还望大佬指出
就到这了我妈喊我洗碗了!!