zoukankan      html  css  js  c++  java
  • entity framework code first migrations

    最近学习了Entity Framework,对code first很感兴趣,赶紧学习下,部署很烦所以在这边写点备注

    code first 有个migration的概念(迁移?)数据创建更新都是围绕这个词

    1、使用初始化的数据库

    1)创建个DEMO控制台项目

    2)使用NuGet下载最新版本的EF,我下了EF5,DLL版本信息是4.4

     打开

    • Tools –> Library Package Manager –> Package Manager Console

    输入Install-Package EntityFramework

    现在写类文件

    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;
     
    namespace MigrationsDemo
    {
        public class BlogContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
        }
     
        public class Blog
        {
            public int BlogId { get; set; }
            public string Name { get; set; }
        }

    在DEMO的MAIN函数写对类的操作

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace MigrationsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db = new BlogContext())
                {
                    db.Blogs.Add(new Blog { Name = "Another Blog " });
                    db.SaveChanges();
     
                    foreach (var blog in db.Blogs)
                    {
                        Console.WriteLine(blog.Name);
                    }
                }
     
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }

    }

    记的APP.CONFIG要配置连接字符串

    如下

     <connectionStrings>
        <add name="test" providerName="System.Data.SqlClient" connectionString="Password=123;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=;" />
      </connectionStrings>

    2、配置migration

    增加个属性

    public string Url { get; set; }
    如果直接使用由于在数据库没有映射会报错 1、
    输入 Enable-Migrations在 Package Manager Console
    2、项目将增加个Migrations文件夹,里面有2个文件
    The Configuration class:使用这个缺省配置就可以
    An InitialCreate migration: 初始化数据库文件,里面记录了如何初始化我们的数据库,文件名会带个时间戳帮忙排序
     
     
     

    3、运行magration

     
    我们主要使用2个命令
    1、Add-Migration :用来生成最新版本migration文件在migrations文件夹
    2、Update-database:将更改更新到数据库
    比如我们上面再加个URL属性
    我们输入Add-Migration AddBlogUrl命令,AddBlogUrl为生成这次更新的文件名
    这样我们的MIGRATIONS文件夹生成了一个名叫AddBlogUrl的文件,这个文件前面有个时间戳
    文件里面代码
    namespace MigrationsDemo.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class AddBlogUrl : DbMigration
        {
            public override void Up()
            {
                AddColumn("Blogs", "Url", c => c.String());
            }
            
            public override void Down()
            {
                DropColumn("Blogs", "Url");
            }
        }
    }
    

    DOWN函数式回滚时候使用的
    现在我们把这些改动更新倒数数据库
    运行Update-DataBase 命令在控制台,默认是更新最新版本的改动
    程序将比较我们更新到数据库历史,将AddBlogUrL 属性更新到数据库
     
     
     

    4、定制化

    增加个属性
    1. public int Rating { get; set; }

    再加个类

    public class Post
    {
        public int PostId { get; set; }
        [MaxLength(200)]
        public string Title { get; set; }
        public string Content { get; set; }
     
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
    增加字段的一些定制

    namespace MigrationsCodeDemo.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
     
        public partial class AddPostClass : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                    "Posts",
                    c => new
                        {
                            PostId = c.Int(nullable: false, identity: true),
                            Title = c.String(maxLength: 200),
                            Content = c.String(),
                            BlogId = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => t.PostId)
                    .ForeignKey("Blogs", t => t.BlogId, cascadeDelete: true)
                    .Index(t => t.BlogId)
                    .Index(p => p.Title, unique: true);
     
                AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
            }
     
            public override void Down()
            {
                DropIndex("Posts", new[] { "Title" });
                DropIndex("Posts", new[] { "BlogId" });
                DropForeignKey("Posts", "BlogId", "Blogs");
                DropColumn("Blogs", "Rating");
                DropTable("Posts");
            }
        }
    }

    运行 Add-Migration AddPostClass in Package Manager Console. 生成MIGRATION文件
    然后运行 Update-Database –Verbose :
    –Verbose参数作用是打出运行的SQL

    5、自定义更新

    到目前为止我们更新数据库的语句都是自动生成的,有时候我们在更新数据库时候要做一些我们的自定义的操作
    public string Abstract { get; set; }
    1、Run the Add-Migration AddPostAbstract command in Package Manager Console.
    如果这个字段需要初始化为POST字段的左边100字符,我们可以再
    AddPostAbstract 文件的UP函数增加
    namespace MigrationsCodeDemo.Migrations { using System; using System.Data.Entity.Migrations; public partial class AddPostAbstract : DbMigration { public override void Up() { AddColumn("Posts", "Abstract", c => c.String()); Sql("UPDATE Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL"); } public override void Down() { DropColumn("Posts", "Abstract"); } }}

    Run the Update-Database –Verbose command in Package Manager Console.
    就可以看出执行的初始化

    6、执行到某个版本(包含回滚哟)

    Update-Database –TargetMigration: AddBlogUrlAddBlogUrl :为要回滚的目标文件名称
    清空数据库命令:Update-Database –TargetMigration: $InitialDatabase
     

    7、SQL脚本

    有时候我们只能通过脚本执行远程服务器时候,EF也提供了一个很好的脚本生成工具 Update-Database -Script -SourceMigration: $InitialDatabase -TargetMigration: AddPostAbstract
    -Script :加上这个参数VS会显示执行的SQL语句 ,从语句可以看到CODE FIRST 使用系统表dbo.__MigrationHistory进行版本控制
     


    8、在程序启动时候自动执行,(初始化到最新版本)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    using MigrationsDemo.Migrations;
     
    namespace MigrationsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>());
     
                using (var db = new BlogContext())
                {
                    db.Blogs.Add(new Blog { Name = "Another Blog " });
                    db.SaveChanges();
     
                    foreach (var blog in db.Blogs)
                    {
                        Console.WriteLine(blog.Name);
                    }
                }
     
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
     Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>()); :将会将数据库初始化最新版本!
    记得加入程序生成的MIGRATIONS的响应命名空间
    初始化不会删除旧数据


    好这次就到这里







  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/xfoolishpig/p/3049812.html
Copyright © 2011-2022 走看看