1. 程式人生 > >Code First 下自動更新數據庫結構(Automatic Migrations)

Code First 下自動更新數據庫結構(Automatic Migrations)

type script exception 判斷 bar sta alt sql bbb

示例 Web.config

技術分享圖片
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </configSections>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <connectionStrings>
        <!--
            需要將 Persist Security Info 設置為 True,以便保存密碼信息
            因為 Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>()); 在判斷 Code First 與數據庫結構是否一致時需要連接 master 庫
        -->
        <add name="MyConnection" providerName="System.Data.SqlClient" connectionString="server=.;database=MyDB;uid=sa;pwd=111111;Persist Security Info=True" />
    </connectionStrings>
</configuration>
技術分享圖片

Product.cs

技術分享圖片
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.ComponentModel.DataAnnotations;

namespace EF43.UpdateSchema
{
    [Table("Product")]
    public class Product
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ProductId { get; set; }

        [Required]
        [Column("ProductName", TypeName="varchar")]
        public string Name { get; set; }

        /*
        為了測試 Automatic Migrations 可放開此註釋,然後 Add-Migration 的話會自動生成結構遷移的相關代碼
        public double Price { get; set; }
        */
    }
}
技術分享圖片

MyContext.cs

技術分享圖片
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Data.Entity;

namespace EF43.UpdateSchema
{
    // 創建的 Context 要繼承自 DbContext
    public class MyContext : DbContext
    {
        // 指定數據庫連接為:connectionStrings 中的 MyConnection
        public MyContext()
            : base("MyConnection")
        {

        }

        public DbSet<Product> Products { get; set; }
    }
}
技術分享圖片

Demo.aspx.cs

技術分享圖片
/*
 * 通過 NuGet 下載 Entity Framework 4.3
 * 
 * 關於 Code First 下自動更新數據庫結構(Automatic Migrations)的相關說明如下:
 * 註:需要通過 NuGet 的 Package Manager Console 輸入相關命令
 * 
 * 在更新了實體結構後輸入如下命令
 * 1、Enable-Migrations
 *     啟動遷移功能,會在項目根目錄下生成 Migrations 文件夾,其內通常會有兩個文件
 *     1. Configuration.cs - 相關配置,如是否需要自動遷移(默認為 false)等
 *     2. 201202290715581_InitialCreate.cs - 未遷移前的數據結構,前半部分為時間戳
 *     
 * 2、Add-Migration -StartupProjectName EF43
 *     在指定的項目中增加一個遷移點,此命令後會要求輸入一個 Name 參數,此參數的值為遷移點名稱
 *     假設輸入的遷移點名稱為 MyFirstTest 則會生成一個類似如下的文件 201202290718442_MyTestFirst.cs,其包含兩個方法 Up() 和 Down(),分別用於此遷移點的升級和降級
 *     
 * 3、Update-Database -StartupProjectName EF43(將指定的項目的數據庫結構升級到最新)
 *     Update-Database -TargetMigration:"201202290718442_MyTestFirst",將當前數據庫結構升級到此遷移點(無參數 -TargetMigration 則為升級到最新)
 *     Update-Database -Script,顯示用於更新數據庫結構的相關 sql 代碼
 *     Update-Database -Script -SourceMigration:"aaa" -TargetMigration:"bbb",顯示將遷移點“aaa”升/降級到遷移點“bbb”的相關 sql 代碼
 *     
 * 註:如果發生“System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation”異常,請查看是否顯示指定了項目名(本例為 -StartupProjectName EF43)
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Data.Entity;

namespace EF43.UpdateSchema
{
    public partial class Demo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            using (var db = new MyContext())
            {
                Random random = new Random();

                var product = new Product { Name = "windows " + random.Next() };
                db.Products.Add(product);

                int recordsAffected = db.SaveChanges();
                Response.Write("影響到數據庫的行數:" + recordsAffected.ToString());
            }
        }
    }
}
技術分享圖片

Migrations/Configuration.cs

技術分享圖片
namespace EF43.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<EF43.UpdateSchema.MyContext>
    {
        public Configuration()
        {
            // 默認情況下不會自動遷移數據庫結構,還有許多其它相關設置,詳看 DbMigrationsConfiguration<TContext>
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(EF43.UpdateSchema.MyContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
}
技術分享圖片

Migrations/201202290715581_InitialCreate.cs

技術分享圖片
namespace EF43.Migrations
{
    using System.Data.Entity.Migrations;
    
    public partial class InitialCreate : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "Product",
                c => new
                    {
                        ProductId = c.Int(nullable: false, identity: true),
                        ProductName = c.String(nullable: false, unicode: false),
                    })
                .PrimaryKey(t => t.ProductId);
            
        }
        
        public override void Down()
        {
            DropTable("Product");
        }
    }
}
技術分享圖片

Migrations/201202290718442_MyTestFirst.cs

技術分享圖片
namespace EF43.Migrations
{
    using System.Data.Entity.Migrations;
    
    public partial class MyTestFirst : DbMigration
    {
        public override void Up()
        {            
            // AddColumn("Product", "Price", c => c.Double(nullable: false));

            // 自動生成的代碼如上,下面是我自定義的,用於設置新增字段的默認值
            // 還有許多其它相關設置,詳看 DbMigration
            AddColumn("Product", "Price", c => c.Double(nullable: false, defaultValue: 10d));
        }
        
        public override void Down()
        {
            DropColumn("Product", "Price");
        }
    }
}
技術分享圖片

Code First 下自動更新數據庫結構(Automatic Migrations)