zoukankan      html  css  js  c++  java
  • Asp.net MVC 中Code First 迁移使用

    如果模型类(数据库上下文类Context和POCO类)发生改变,与数据库中的结构不一致,系统默认会抛出一个异常。可以考虑使用代码优先迁移。

    代码优先迁移执行UpSert数据库操作,它在每一次更新数据库(Update-Database)后执行,添加数据库中没有的记录,更新数据库已有的记录,通过UI添加的记录保持不变。(模型更改后需要重新编译程序,并修改各视图和方法绑定的白名单,如果不是第一次迁移,还需要设置迁移文件交下configtion.cs文件中的seed方法增加或改变字段。)执行步骤如下:

    1、启用迁移。在库程序包控制台输入Enable-Migrations,(如果多个上下文对象,需要指定完整的上下文类,包括所在的命名空间如Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext),自动创建一个Migration 迁移文件夹,并在下面创建一个Configurations.cs的文件。可以在里面设置种子方法。

     protected override void Seed(MvcMovie.Models.MovieDBContext context)
            {
                List<Movie> movies =new List<Movie>
                {
                   new Movie{ Title="封神榜",ReleaseDate=DateTime.Parse("2015-1-10"),Genre="神话",Price=50.6M,Rating="成人" },
                   new Movie{ Title="喜羊羊与灰太狼",ReleaseDate=DateTime.Parse("2008-5-1"),Genre="卡通",Price=30.2M,Rating="儿童" },
                   new Movie{ Title="何以笙箫默",ReleaseDate=DateTime.Parse("2014-11-5"),Genre="爱情",Price=102.5M,Rating="成人" },
                   new Movie{ Title="倚天屠龙记",ReleaseDate=DateTime.Parse("2010-7-1"),Genre="武侠",Price=70.05M,Rating="成人" },
                   new Movie{ Title="天龙八部",ReleaseDate=DateTime.Parse("1998-8-8"),Genre="武侠",Price=200.2M,Rating="成人" },
                   new Movie{ Title="全面回忆",ReleaseDate=DateTime.Parse("2012-6-10"),Genre="科幻",Price=80.3M,Rating="成人" },
                   new Movie{ Title="黑衣人",ReleaseDate=DateTime.Parse("2014-6-12"),Genre="科幻",Price=150.3M,Rating="成人" },
                   new Movie{ Title="熊出没",ReleaseDate=DateTime.Parse("2013-8-13"),Genre="卡通",Price=40.6M,Rating="儿童" },
                   new Movie{ Title="西游记",ReleaseDate=DateTime.Parse("1984-5-21"),Genre="神话",Price=110.05M,Rating="成人" },

                };

                movies.ForEach(m => context.Movies.AddOrUpdate(s => s.Title, m));

              //或者  context.Movies.AddOrUpdate(m => m.Title, movies.ToArray());
                context.SaveChanges();

            }

    2、创建迁移。在库程序包控制台输入 Add-Migration Rating。程序将比对模型类(数据库上下文类Context和POCO类)与数据库的一致性,将创建一个时间戳+迁移名字的cs文件,里面包含有根据模型类创建更改数据库的UP方法。可以在执行UpDate-Database 前创建多个迁移,然后它们能按照顺序依次执行,是因为在每个迁移文件前有一个时间戳。

    同时

    3、升级数据库。编译程序,在库程序包控制台输入 Update-Database 。第一个任务是将运行当前的迁移文件中的代码对数据库更改UP方法,第二是报告迁移配置文件中的Seed方法upsert数据,通过UI更改的数据如与Seed方法中的数据不一致,将还原成种子方法的数据。通过UI新增的数据能保存。

    4、如果没有对模型作任何更改,运行update-database,就不会执行迁移,但会再次运行Seed方法,如果在UI界面中修改了Seed方法中的记录,数据库中的记录将还原成种子方法的记录值。

    二、如果一个项目中有多个上下文类,在创建迁移的时候需要指定详细的上下文类或者指定可选的迁移文件夹目录,以防冲突。如果一个项目中有多个迁移,增加迁移和升级数据库时同样需要指定详细的迁移配置文件。

    比如:1、一个项目中有多个上下文类,启用迁移 

    Enable-Migrations -ContextTypeName SimpleSite.Models.ApplicationDbContext -MigrationsDirectory MigrationsIdentity

       2、增加迁移:Add-Migration CssTheme -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration

    3、升级数据库:Update-Database -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration

    示例:
    启用迁移:  Enable-Migrations -ContextTypeName MajorConstruction.Models.MajorContext 如果不指定-MigrationsDirectory 默认是迁移文件是在项目的Migrations 文件夹下面。
    增加迁移:Add-Migration ArticleIsShow -ConfigurationTypeName MajorConstruction.Migrations.Configuration
    升级数据库:Update-Database -ConfigurationTypeName MajorConstruction.Migrations.Configuration
    如果迁移是增加或修改必填写字段,如Boolean值。则可以修改有时间戳的迁移文件中指定默认值,因为执行升级数据库命令后,先是运行迁移文件中的UP方法,再运行Configuration配置文件下的 Seed种子方法。
    如:

    public partial class ArticleIsShow : DbMigration
    {
    public override void Up()
    {
    AddColumn("dbo.Article", "ArticleIsShow", c => c.Boolean(nullable: false,defaultValue:true));
    }

    public override void Down()
    {
    DropColumn("dbo.Article", "ArticleIsShow");
    }
    }
    }



    三、可以在数据库上下文类中,为数据库上下文中指定连接字符串,多个上下文可以指定同一个连接字符串(但他们拥有不同的Dbset,也就是不同的实体集也就是对应的表),这样,就可以访问同一个数据库。同时,还可以在配置文件中,修改约定。

    public class SiteDataContext:DbContext
    {
    public SiteDataContext() : base("DefaultConnection") { } //调用基类的构造函数。

    public DbSet<Notification> Notifications { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

    当对数据库中已有数据的情况下执行迁移,需要插入存根数据来满足表格的外键约束,比如有表格新增了一列不能为空的外键。可以在UP方法中建立一个临时的值记录作为默认的值满足外键约束,在up方法中,所有的记录都设置为这个默认值,然后种子方法会将有些记录设置成正确的值。

    比如 原来的Course  实体没有DepartmentID 这个属性,而本次迁移执行前,数据库中已经有了记录了。

    就需要在迁移文件中为DepartmentID 指定默认值.

    // Create a department for course to point to. Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())"); // default value for FK points to department created above. AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false, defaultValue: 1)); //AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false));

    对于多对多关系,EF Code First 会自动创建关联的 各主键约束表格,但可以通过Fluent API配置表格的列名和表名。

    modelBuilder.Entity<Course>() .HasMany(c => c.Instructors).WithMany(i => i.Courses) .Map(t => t.MapLeftKey("CourseID") .MapRightKey("InstructorID")



     

  • 相关阅读:
    android 使用Activity做窗口弹出(模拟Dialog)
    解决ListView 跟ScroolView 共存 listItem.measure(0, 0) 空指针
    基于iview使用jsx扩展成可编辑的表格
    vue token 过期处理
    组件通信 eventtBus
    组件通信 $ref
    组件通信 Provide&&inject
    Vue 生命周期
    layui token 过期 重新登陆
    Python(3) 进制转换
  • 原文地址:https://www.cnblogs.com/liuyuanhao/p/4319637.html
Copyright © 2011-2022 走看看