• EF4.3 基于代码的迁移演练


    原文地址:http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx

    原文名称:EF 4.3 Code-Based Migrations Walkthrough

    准备工作

    在开始之前,我们需要一个项目,以及一个 Code First 的模型,对于这次演示,我们使用典型的博客 Blog 和回复 Post 模型。

    1. 创建新的 MigrationsCodeDemo 控制台应用程序

    2. 为项目添加最新版本的 EntityFramework NuGet 包。

    找到包管理器控制台。

    运行 Install-Package EntityFramework 命令。

    成功之后的项目文件如下:

    创建初始的模型和数据库

    1. 增加如下的 Model.cs 文件,代码定义了一个单个的 Blog 类表示我们的模型对象,BlogContext 类就是 EF Code First 的上下文。

    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;

    namespace MigrationsCodeDemo
    {
    public class BlogContext : DbContext
    {
    public DbSet<Blog> Blogs { get; set; }
    }

    public class Blog
    {
    public int BlogId { get; set; }
    public string Name { get; set
    ; }
    }
    }

    2. 现在我们已经有了一个模型,是时候进行一次数据访问了。使用如下的代码更新 Program.cs 文件。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MigrationsCodeDemo
    {
    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);
    }
    }
    }
    }
    }

    3. 运行程序,现在就可以在你本地的 SQLExpress 数据库中看到数据库了。

    启用迁移

    1. 在 Blog 类中增加一个 Url 属性。

        public class Blog
    {
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    }

    2. 现在运行程序,会看到如下的异常。
    未经处理的异常:  System.InvalidOperationException: The model backing the 'BlogContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

    3. 正如异常建议,现在是开始使用 Code First 迁移的时候了,第一步是为我们的上下文启用迁移支持。

       在包管理器的控制台中执行命令:Enable-Migrations

    4. 这个命令在项目中增加名为 Migrations 文件夹,文件夹中包含两个文件。

    Configuration 类,这个类允许你配置你的上下文的迁移行为,在这个演示中,我们仅仅使用默认配置。

    因为在这个项目中只有一个上下文,Enable-Migrations 自动填充应用的这个上下文。

    201202171353373_InitialCreate.cs 中的 InitialCreate ,生成这个迁移是因为我们已经通过 Code First 创建了一个数据库。这个迁移中的代码表示我们已经创建的数据库,

    namespace MigrationsCodeDemo.Migrations
    {
    using System.Data.Entity.Migrations;

    public partial class InitialCreate : DbMigration
    {
    public override void Up()
    {
    CreateTable(
    "Blogs",
    c => new
    {
    BlogId = c.Int(nullable: false, identity: true),
    Name = c.String(),
    })
    .PrimaryKey(t => t.BlogId);

    }

    public override void Down()
    {
    DropTable("Blogs"
    );
    }
    }
    }

    第一个迁移

    你会使用到两个命令

    Add-Migration,将会基于你对模型的修改创建一个迁移的脚手架。

    Update-Database,将没有提交的修改提交到数据库。

    1. 我们首先为我们新增加的 Url 属性创建一个迁移,Add-Migration 会帮我们完成这个工作,我们为这个迁移命名为:AddBlogUrl。

     执行:Add-Migration AddBlogUrl

    项目中增加了一个文件 201202171413369_AddBlogUrl.cs

     

    内容如下:

    namespace MigrationsCodeDemo.Migrations
    {
    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"
    );
    }
    }
    }

    3. 我们可以在这个迁移中编辑或者增加内容,但是现在看起来就很不错,让我们将这个迁移提交到数据库中。

    执行: Update-Database

    4. 现在的数据库中已经包含了 Url 列。

    定制迁移

    下面我们看看如何定制迁移。

    1. 在代码中增加一个回复的类 Post,同时在 Blog 中增加一个评分属性。

    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;

    namespace MigrationsCodeDemo
    {
    public class Blog
    {
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public int Rating { get; set; }
    public List<Post> Posts { 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; }
    }
    }

    2. 使用 Add-Migration 命令创建一个迁移,命名为 AddPostClass。

    3.  Code First Migrations 帮我们创建好了一个迁移,但是我们希望能增加如下的修改:

         首先,为 Posts.Title 增加一个唯一索引。

         增加一个非空的 Blogs.Rating 列,如果表中已经存在了数据,那么就将 CLR 默认的数据类型值赋予新增加的列 (Rating 是整数类型,应该就是 0), 但是,我们希望默认为 3, 这样已经存在的博客会有一个不错的评分。

    namespace MigrationsCodeDemo.Migrations
    {
    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[] { "BlogId" });
    DropForeignKey("Posts", "BlogId", "Blogs");
    DropColumn("Blogs", "Rating");
    DropTable("Posts"
    );
    }
    }
    }

    4. 运行 Update-Database 提交到数据库,这次可以使用一个参数 -Verbose,以便可以看到生成的 SQL 脚本。

    数据操作/定制 SQL

    我们已经完成的迁移并没有修改或者移动任何数据,我们可以在迁移中的任何地点运行任意脚本。

    1. 在模型上增加一个摘要 PostAbstrack 属性,然后,希望使用已经发布的内容来填充这个摘要属性。

    public class Post
    {
    public int PostId { get; set; }
    [MaxLength(200)]
    public string Title { get; set; }
    public string Content { get; set; }
    public string Abstract { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set
    ; }
    }

    2. 创建一个迁移。

    3. 修改生成的迁移文件,

    namespace MigrationsCodeDemo.Migrations
    {
    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"
    );
    }
    }
    }

    4. 更新数据库之后,就会得到最新的数据了。使用 Verbose 参数可以看到提交的脚本。

  • 相关阅读:
    接口和抽象类的区别
    MFC之ListCtrl动态添加按钮
    C++类间转换之dynamic_cast
    字符串提取
    C++实现快速排序
    MFC中CListCtrl类依靠CImageList贴图并显示不同图像
    北工大耿丹学院16级计科院3班C语言课程助教学期总结
    C语言课程2——我们交流的工具:Coding.net
    salt-minion安装脚本
    zabbix邮件报警脚本
  • 原文地址:https://www.cnblogs.com/wmlunge/p/2851352.html
Copyright © 2020-2023  润新知