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的响应命名空间
初始化不会删除旧数据


好这次就到这里







原文地址:https://www.cnblogs.com/xfoolishpig/p/3049812.html