• EF实体框架之CodeFirst八


    前面七篇基本把Code First学习了一下,不过code first中会出现一个问题,就是数据迁移的问题。

    一、数据准备

    还是在前面的demo上修改,这次使用Province和City类。

        public class Province
        {
            [Key]
            public string  ProvinceId { get; set; }
    
            public string ProvinceName { get; set; }
    
            public virtual ICollection<City> Citys { get; set; }
        }
    }
        public class City
        {
            public int CityId { get; set; }
    
            public string CityName { get; set; }
    
            public string ProId { get; set; }
    
            [ForeignKey("ProId")]//ProId一对要存在
            public Province Province { get; set; }
    
        }
            static void Main(string[] args)
            {
                City cityA = new City() { CityName = "驻马店" };
                City cityB = new City() { CityName = "周口" };
                Province province = new Province() {ProvinceId="001", ProvinceName = "河南省", Citys = new List<City>() { cityA, cityB } };
                using (var db = new EFCodeFirstDbContext())
                {
                    db.Provinces.Add(province);
                    db.SaveChanges();
                    Console.WriteLine("Success");
                }
                Console.ReadKey();
            }

    上面的会在数据库映射如下面的数据表

    二、数据迁移

    1.增加属性

    在City类中增加一个属性 Description,在创建City对象时增加Description,再次运行会报下面的错误。

    通过下面图的步骤打开程序包管理器控制台.

    在上面的控制台输入下面的code,这个在默认项目上要选择正确,会在项目上增加Migrations文件夹和Configuration.cs类。

    Enable-Migrations -EnableAutomaticMigrations

    namespace EFCodeFirstDataAccess.Migrations
    {
        using System;
        using System.Data.Entity;
        using System.Data.Entity.Migrations;
        using System.Linq;
    
        internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDataAccess.EFCodeFirstDbContext>
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = true;
                ContextKey = "EFCodeFirstDataAccess.EFCodeFirstDbContext";
            }
    
            protected override void Seed(EFCodeFirstDataAccess.EFCodeFirstDbContext context)
            {
                //  This method will be called after migrating to the latest version.
    
                //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
                //  to avoid creating duplicate seed data. E.g.
                //
                //    context.People.AddOrUpdate(
                //      p => p.FullName,
                //      new Person { FullName = "Andrew Peters" },
                //      new Person { FullName = "Brice Lambson" },
                //      new Person { FullName = "Rowan Miller" }
                //    );
                //
            }
        }
    }

    然后执行下面的code

    Add-Migration InitialCreate

    然后会生成一个201609061311422_InitialCreate.cs类。

    namespace EFCodeFirstDataAccess.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class InitialCreate : DbMigration
        {
            public override void Up()
            {
                AddColumn("dbo.Cities", "Description", c => c.String());
            }
            
            public override void Down()
            {
                DropColumn("dbo.Cities", "Description");
            }
        }
    }

    执行下面的code生成与上面一致的数据库

    Update-Database -Verbose

    此时再次运行上面的C#代码就不会再报错。而且数据库的结构也和C#的相对应了。

    2.增加类

    在数据库模型中添加User类,执行程序包管理器控制台语句,Migrations文件夹中新增类文件

     Add-Migration AddUser

    此时会在项目中增加201609061323573_AddUser.cs类。

    namespace EFCodeFirstDataAccess.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class AddUser : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                    "dbo.Users",
                    c => new
                        {
                            UserId = c.Int(nullable: false, identity: true),
                            Name = c.String(),
                            Age = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => t.UserId);
                
            }
            
            public override void Down()
            {
                DropTable("dbo.Users");
            }
        }
    }

    再次执行下面的code

     Update-Database -Verbose

    此时再次运行C#项目会在数据库中映射出一个Users表

    3.删除属性

    这次删除User类中的Age属性。依次执行下面的两行

    Add-Migration ModifyUser

    上面的一行会生成一个201609061334085_ModifyUser.cs类。

    namespace EFCodeFirstDataAccess.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class ModifyUser : DbMigration
        {
            public override void Up()
            {
                DropColumn("dbo.Users", "Age");
            }
            
            public override void Down()
            {
                AddColumn("dbo.Users", "Age", c => c.Int(nullable: false));
            }
        }
    }

    然后更新到数据库

    Update-Database -Verbose

    4.版本回溯

    在项目中可能会存在版本回溯的情况,code first也有对应的解决方案。

    Update-Database –TargetMigration: AddUser

    Update-Database -Verbose

    如果你想回滚一切至空数据库,可以使用命令 Update-Database –TargetMigration: $InitialDatabase,此时要在Configuration.cs中设置AutomaticMigrationDataLossAllowed = true;

    5.生成数据库版本之间的Sql脚本

    执行程序包管理器控制台语句,生成数据库版本之间的Sql脚本。该操作仅为生成Sql语句,并未在数据库中进行执行。其中-TargetMigration在未指定的情况,默认为迁移到最新的版本。

     Update-Database -Script -SourceMigration:InitialCreate -TargetMigration:ModifyUser

  • 相关阅读:
    网络流24题-运输问题
    ASP.NET API
    面向对象理解
    冒泡排序
    HTTP Header 缓存
    HTTP Header
    Flask学习笔记07之模板渲染
    Flask学习笔记06之@before_request请求之前执行
    Flask报错:AssertionError: View function mapping is overwriting an existing endpoint function: inner
    装饰器03之多个装饰器的执行顺序
  • 原文地址:https://www.cnblogs.com/5ishare/p/5847377.html
Copyright © 2020-2023  润新知