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


    好这次就到这里







  • 相关阅读:
    DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作
    DevExpress ASP.NET 使用经验谈(4)-CriteriaOperator的使用
    DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接)
    DevExpress ASP.NET 使用经验谈(2)-XPO对象的使用(使用默认数据连接)
    DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建
    C#堆栈原理(我有两个例子测试你到底会不会)
    C# static 干货全解析
    C# 链接 SQLite问题汇总
    EFCore AsNoTracking方法不能使用的问题;EFCore 如何取消跟踪
    2019-1-3 每日一记
  • 原文地址:https://www.cnblogs.com/xfoolishpig/p/3049812.html
Copyright © 2011-2022 走看看