关于EntityFramework数据迁移原理

查询数据库的表"__MigrationHistory",遍历代码库的Migrations文件夹下的所有文件,如果文件不在__MigrationHistory表内,那么就执行迁移。

有了上面的原理之后,我们来看一下如果我们不小心手动删除了一个表,如何在不影响其它表的情况下来恢复你删除的表:

方法一:

关于Model 以及 DBContext如下:

   public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; } public string Url { get; set; }
public virtual List<Post> Posts { get; set; }
} public class User
{
[Key]
public int UserId { get; set; }
public string Username { get; set; }
public string DisplayName { get; set; }
//public int? age { get; set; }
//public string interest { get; set; }
} public class School
{
public int SchoolId { get; set; } public string SchoolName { get; set; } public int SchoolLevel { get; set; }
} public class Teacher
{
[Key]
public int TecherId { get; set; }
public string TeacherName { get; set; }
} public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; } public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
} public class Tutorial
{
[Key]
public int Id { get; set; } public int Name { get; set; }
} public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; } public DbSet<User> Users { get; set; } public DbSet<Tutorial> Tutorials { get; set; }
public DbSet<School> Schools { get; set; } public DbSet<Teacher> Teachers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Property(u => u.DisplayName).HasColumnName("display_name");
modelBuilder.Entity<User>().Property(u => u.Username).HasColumnName("user_name");
}
}

  

migrations 文件夹下的文件如下:

对应数据库中的记录为:

假如此时我们手动删除了schools表,此时我们应该找到schools表的创建与修改的迁移code是在哪个Migrations文件夹下面的哪个文件,找到对应的文件

我们这里是在201503190341085_addmodels.cs中,

   public partial class addmodels : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Blogs",
c => new
{
BlogId = c.Int(nullable: false, identity: true),
Name = c.String(),
Url = c.String(),
})
.PrimaryKey(t => t.BlogId); CreateTable(
"dbo.Posts",
c => new
{
PostId = c.Int(nullable: false, identity: true),
Title = c.String(),
Content = c.String(),
BlogId = c.Int(nullable: false),
})
.PrimaryKey(t => t.PostId)
.ForeignKey("dbo.Blogs", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId); CreateTable(
"dbo.Schools",
c => new
{
SchoolId = c.Int(nullable: false, identity: true),
SchoolName = c.String(),
SchoolLevel = c.Int(nullable: false),
})
.PrimaryKey(t => t.SchoolId); CreateTable(
"dbo.Tutorials",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id); CreateTable(
"dbo.Users",
c => new
{
UserId = c.Int(nullable: false, identity: true),
user_name = c.String(),
display_name = c.String(),
})
.PrimaryKey(t => t.UserId); } public override void Down()
{
DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
DropIndex("dbo.Posts", new[] { "BlogId" });
DropTable("dbo.Users");
DropTable("dbo.Tutorials");
DropTable("dbo.Schools");
DropTable("dbo.Posts");
DropTable("dbo.Blogs");
}
}

  

此时我们要做的只要把这个文件名201503190341085_addmodels.cs对应在数据迁移表中的记录删除,

delete __MigrationHistory where MigrationId = '201503190341085_addmodels' ,然后我们在201503190341085_addmodels.cs注释掉其它的迁移数据,只留下创建shools表的数据

    public partial class addmodels : DbMigration
{
public override void Up()
{
//CreateTable(
// "dbo.Blogs",
// c => new
// {
// BlogId = c.Int(nullable: false, identity: true),
// Name = c.String(),
// Url = c.String(),
// })
// .PrimaryKey(t => t.BlogId); //CreateTable(
// "dbo.Posts",
// c => new
// {
// PostId = c.Int(nullable: false, identity: true),
// Title = c.String(),
// Content = c.String(),
// BlogId = c.Int(nullable: false),
// })
// .PrimaryKey(t => t.PostId)
// .ForeignKey("dbo.Blogs", t => t.BlogId, cascadeDelete: true)
// .Index(t => t.BlogId); CreateTable(
"dbo.Schools",
c => new
{
SchoolId = c.Int(nullable: false, identity: true),
SchoolName = c.String(),
SchoolLevel = c.Int(nullable: false),
})
.PrimaryKey(t => t.SchoolId); //CreateTable(
// "dbo.Tutorials",
// c => new
// {
// Id = c.Int(nullable: false, identity: true),
// Name = c.Int(nullable: false),
// })
// .PrimaryKey(t => t.Id); //CreateTable(
// "dbo.Users",
// c => new
// {
// UserId = c.Int(nullable: false, identity: true),
// user_name = c.String(),
// display_name = c.String(),
// })
// .PrimaryKey(t => t.UserId); } public override void Down()
{
//DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
//DropIndex("dbo.Posts", new[] { "BlogId" });
//DropTable("dbo.Users");
//DropTable("dbo.Tutorials");
DropTable("dbo.Schools");
//DropTable("dbo.Posts");
//DropTable("dbo.Blogs");
}
}

  

此时如果你在package-manager console 中执行update-database 即可完成schools表的恢复

方法二:

利用 Update-Database -Script -SourceMigration $InitialDatabase (这是一个变量不需要你去改成你自己的数据库名字)  或者

Update-Database -Script -SourceMigration Second -TargetMigration First (用这两个中的哪个是视情况而定的)
(Second First 就是你的migrations文件夹下的文件名字的后面那个 比喻 201503190906406_addmodels 你就输入 Update-Database -Script -SourceMigration addmodels)
这样会产生一个脚本文件,你在那个脚本文件中找出你恢复的表的一些创建或者修改信息

我找到了Schools的创建SQL , 在数据库中执行即可:

CREATE TABLE [dbo].[Schools] (
[SchoolId] [int] NOT NULL IDENTITY,
[SchoolName] [nvarchar](max),
[SchoolLevel] [int] NOT NULL,
CONSTRAINT [PK_dbo.Schools] PRIMARY KEY ([SchoolId])
)

  

这样你就恢复好了

Entity framework 意外删除了表,如何在不影响其它表的情况下恢复回来的更多相关文章

  1. mvc+entity framework database first,生成的model每次更新一个表会更新所有的model

    在使用Entity Framework 的Database frist或model first时,直接加attribute到modle类上是太现实也不合理的,因为model类是自动生成的,重新生成后会 ...

  2. Oracle备份恢复之无备份情况下恢复undo表空间

    UNDO表空间存储着DML操作数据块的前镜像数据,在数据回滚,一致性读,闪回操作,实例恢复的时候都可能用到UNDO表空间中的数据.如果在生产过程中丢失或破坏了UNDO表空间,可能导致某些事务无法回滚, ...

  3. 在注册表中无Python3.5安装路径的情况下安装pywin32-

    当安装pywin32出现Python Version 3.5 required which was not found in the registry的时候表面注册表中没有Python3.5的安装路径 ...

  4. 在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据

    当把mysql容器销毁,在新建一个容器,进行之前的数据恢复. 因为之前建立了数据卷,那么现在就可以利用这个数据卷进行数据恢复. 使用docker volume create volume_name命令 ...

  5. Entity Framework 5.0系列之自动生成Code First代码

    在前面的文章中我们提到Entity Framework的"Code First"模式也同样可以基于现有数据库进行开发.今天就让我们一起看一下使用Entity Framework P ...

  6. 【转】Entity Framework 5.0系列之自动生成Code First代码

    在前面的文章中我们提到Entity Framework的“Code First”模式也同样可以基于现有数据库进行开发.今天就让我们一起看一下使用Entity Framework Power Tools ...

  7. (转)Entity Framework 5.0系列之自动生成Code First代码

    原文地址:http://www.cnblogs.com/kenshincui/archive/2013/08/29/3290527.html 在前面的文章中我们提到Entity Framework的“ ...

  8. 让Entity Framework启动不再效验__MigrationHistory表

    Entity Framework中DbContext首次加载OnModelCreating会检查__MigrationHistory表,作为使用Code Frist编程模式,而实际先有数据库时,这种检 ...

  9. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

随机推荐

  1. Kafka、RabbitMQ、RocketMQ、ActiveMQ消息中间件的对比--多年生产经验实践总结

    引言 分布式系统中,我们广泛运用消息中间件进行系统间的数据交换,便于异步解耦.现在开源的消息中间件有很多,前段时间我们自家的产品 RocketMQ (MetaQ的内核) 也顺利开源,得到大家的关注. ...

  2. openwrt环境中某个运行在host端的软件如何安装到openwrt的$(STAGING_DIR_HOST)/bin下

    可参考示例:见'git grep host-build.mk package/{system,utils}'

  3. Angular 中的生命周期函数

    一. Angular中的生命周期函数 官方文档:https://www.angular.cn/guide/lifecycle-hooks 生命周期函数通俗的讲就是组件创建.组件更新.组件销毁的时候会触 ...

  4. 分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案

    问题: 在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性.但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了. 当这个方 ...

  5. Spring的AOP原理

    转自 https://www.tianmaying.com/tutorial/spring-aop AOP是什么? 软件工程有一个基本原则叫做“关注点分离”(Concern Separation),通 ...

  6. python选课系统demo的小练习

    #简化选课系统代码:先登陆,然后判断身份并实例化,根据身份对应的类,让用户选择 class Manager: operate_dict=[ ('创造学生账号',"creat_student& ...

  7. Qt598x64vs2017.Kit(构建套件)(安装Qt598x86vs2015)

    1.Qt598-->工具-->选项 1.1. 1.2. 2.20191120 想起 上面第一张图的配置编译器的地方,就想着 Qt598x64vs2017 配置成编译x86,于是将 上面图中 ...

  8. Mysql统计每年每个月的数据——详细教程

    Mysql统计每年每个月的数据(前端页面统计图实现) 最终想实现的效果图,在这里就不多废话了,直接上效果图,由于测试数据有几个月是为0的,所以数据图看着会有点怪怪. 接下来是数据库的两个表,这里直接给 ...

  9. C#使用Castle实现AOP面向切面编程

    Castle.Core 本质是创建继承原来类的代理类,重写虚方法实现AOP功能.个人觉得比Autofac用着爽 使用方式比较简单,先新建一个控制台项目,然后在Nuget上搜索Castle.Core并安 ...

  10. Flink中API使用详细范例--window

    Flink Window机制范例实录: 什么是Window?有哪些用途? 1.window又可以分为基于时间(Time-based)的window 2.基于数量(Count-based)的window ...