code first 數據遷移,表 ,數據修改

 

原文:Entity Framework CodeFirst數據遷移

 

前言

緊接着前面一篇博文Entity Framework CodeFirst嘗試

我們知道無論是“Database First”還是“Model First”當模型發生改變了都可以通過Visual Studio設計視圖進行更新,那麼對於Code First如何更新已有的模型呢?今天我們簡單介紹一下Entity Framework的數據遷移功能。

Entity Framework配置

 當我們對項目進行Entity Framework進行安裝引用的時候,同時生成了兩個配置文件

packages.config文件:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="5.0.0" targetFramework="net45" />
</packages>

 App.config文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

 packages.config內容比較簡單,首先是EF自身版本,然後在安裝過程中根據當前應用的.NET Framework版本配置了“targetFramework”,因爲不同的.NET Framework版本對應的EF程序集不同,這在安裝過程中會自動識別並配置。

App.config中自動添加了“entityFramework”配置節,在EF包安裝過程中自動根據當前環境配置了“defaultConnectionFactory”, “defaultConnectionFactory”是EF默認的連接配置,只有在沒有配置連接字符串時生效。

 配置了數據庫鏈接字符串的App.config配置文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="CodeFirstTest" connectionString="Data Source=.;Database=CodeFirstTest;UID=sa;PWD=sa123;" providerName="System.Data.SqlClient"></add>
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

CodeFirst 數據遷移

現在讓我們在上一篇文章的Entity Framework CodeFirst嘗試 的基礎上給Order添加一個"Employee”屬性,然後運行,不出意外的話你將看到如下異常:

 

 從異常信息我們可以看出,EF已經檢測到模型發生了改變,建議我們使用”Code First Migrations”對模型進行更新。

在開始Code First數據庫遷移之前,我們先對上一節編寫的OrderTestContext類進行修改添加默認構造函數,因爲Code First Migrations將會使用數據庫上下文的默認構造函數進行數據遷移操作(儘管沒有默認構造函數所有的數據操作都能正常進行,但是對於數據遷移這是必須的),因此我們需要添加一個默認構造函數,並且該構造函數中必須傳入我們的數據庫連接名稱,否則將會把更新應用到EF默認數據庫上。下面是我們的OrderTestContext:

    public class OrderTestContext:DbContext
    {
        public OrderTestContext():base("CodeFirstTest")
        { 
            
        }

        public OrderTestContext(string connectionName)
            : base(connectionName)
        {
        }
        public DbSet<Order> Orders { get;set;}

        public DbSet<OrderDetail> OrderDetails { get; set; }
    }

 

下面我們將藉助於”Code First Magrations” 進行模型更新。然後找到如下圖所示的位置

1.在“程序包管理器控制檯”鍵入命令:Enable-Migrations -ProjectName  CodeFirstTest

 

如果多次執行此命令可以添加-Force參數

添加後,項目中添加了一個名爲Migrations的文件夾

 

查看Configuration文件中的代碼爲:

namespace CodeFirstTest.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<CodeFirstTest.OrderTestContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(CodeFirstTest.OrderTestContext 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" }
            //    );
            //
        }
    }
}

 方法Seed中可以進行數據遷移後的數據初始化工作,將在每次遷移之後運行。如上代碼所示,AddOrUpdate是IDbSet<TEntity>的擴展方法,如果指定條件的數據不存在,則會添加,如果存在,會更新。所以,如果數據是通過此方法來初始化的,在與業務更新之後,再次進行數據遷移後,還是會被還原。

還有一個名爲InitialCreate的類,配置生成數據庫的細節:

namespace CodeFirstTest.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class InitialCreate : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Orders",
                c => new
                    {
                        ID = c.Int(nullable: false, identity: true),
                        Customer = c.String(),
                        OrderDate = c.DateTime(nullable: false),
                    })
                .PrimaryKey(t => t.ID);
            
            CreateTable(
                "dbo.OrderDetails",
                c => new
                    {
                        ID = c.Int(nullable: false, identity: true),
                        Product = c.String(),
                        OrderID = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.ID)
                .ForeignKey("dbo.Orders", t => t.OrderID, cascadeDelete: true)
                .Index(t => t.OrderID);
            
        }
        
        public override void Down()
        {
            DropIndex("dbo.OrderDetails", new[] { "OrderID" });
            DropForeignKey("dbo.OrderDetails", "OrderID", "dbo.Orders");
            DropTable("dbo.OrderDetails");
            DropTable("dbo.Orders");
        }
    }
}

 

3.執行“Add-Migration AddEmployee”命令,添加一個名爲AddEmployee的遷移

 

4.執行“Update-Database”命令,更新數據庫架構

如果更新數據庫存在衝突而不能執行更新,可以添加 -Force強制執行,例如:“Update-Database -Force”

5.設置自動遷移

每次都通過控制檯來進行遷移太過麻煩,可以設置爲自動遷移。

  1. AutomaticMigrationsEnabled:獲取或設置 指示遷移數據庫時是否可使用自動遷移的值。

  2. AutomaticMigrationDataLossAllowed:獲取或設置 指示是否可接受自動遷移期間的數據丟失的值。如果設置爲false,則將在數據丟失可能作爲自動遷移一部分出現時引發異常。

代碼調用實例

            using (var db = new OrderTestContext("CodeFirstTest"))
            {
                Order Order = new Order();
                Order.Customer = "aehyok";
                Order.OrderDate = DateTime.Now;
                db.Orders.Add(Order);
                db.SaveChanges();

                IQueryable<Order> Orders = from Orderes in db.Orders
                                           select Orderes;
                foreach (Order O in Orders)
                {
                    Console.WriteLine("OrderID is {0},Customer is {1}", O.ID, O.Customer);
                }
            }

 

 調用結果展示

有兩條數據,一條是上一篇博文添加的數據,第二條就是今天測試添加的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章