您的位置:首页 > 其它

Entity Framework Code First (八)迁移 Migrations

2016-04-28 14:48 316 查看



评论 - 157


Entity Framework Code
First (八)迁移 Migrations

创建初始模型和数据库
  在开始使用迁移(Migrations)之前,我们需要一个 Project 和一个 Code First Model,
对于本文将使用典型的 Blog 和 Post 模型

创建一个新的控制台应用程序 MigrationsDemo;
添加最新的 EntityFramework 到项目

Tools –> Library Package Manager –> Package Manager Console;
运行命令 Install-Package EntityFramework  

创建 Blog.cs 和 DbContext 的派生类 BlogContext.cs

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


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


  更改 Program.cs 以调用

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();
}


  运行查看结果



  发现如上错误"CREATE DATABSE permission denied in databse 'master'"
  我们在 BlogContext 上的无参构造函数上添加诊断代码并设置调试断点

System.Diagnostics.Debug.Write(Database.Connection.ConnectionString);


  再次运行



  我们注意到 Data Scource 竟然是 .\\SQLEXPRESS 而不是我们想要的 localDB ,
这是因为:

如果我们安装了 SQL Express,那么 database 将会安装在 local SQL Express instance,否则 Code
First 才将尝试使用 localDB;
SQL Express 总是具有优先权,只要安装了它

  知道了原因我们就好解决了:

如果想继续使用 SQL Express,那么就配置相应地权限,请参考 http://odetocode.com/Blogs/scott/archive/2012/08/14/a-troubleshooting-guide-for-entity-framework-connections-amp-migrations.aspx; 如果想改用 localDB, 只需在.config 配置即可(放在 configSections 节点后面)

<connectionStrings>
<add name="BlogContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=BlogContext;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
</connectionStrings>


  再次运行就行了,让我们看一下后台生成的数据库



启用迁移
  我们对模型 Blog 做一些更改:增加一个 Url 属性

public string Url { get; set; }


  我们此时再次运行程序,发现如下错误



  'InvalidOperationException' was unhandled. 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)
  正如错误消息提示的那样,是时候使用 Code First Migrations,第一步是运行如下的命令:

在 Package Manager Console 下运行命令 Enable-Migrations





  这个命令将在项目下创建文件夹 Migrations

The Configuration class 这个类允许你去配置如何迁移,对于本文将使用默认的配置(在本文中因为只有一个 Context, Enable-Migrations 将自动对 context
type 作出适配);
An InitialCreate migration (本文为 201312240822431_InitialCreate.cs)这个迁移之所以存在是因为我们之前用 Code
First 创建了数据库, 在启用迁移前,scaffolded migration 里的代码表示在数据库中已经创建的对象,本文中即为表 Blog (列 BlogId 和 Name).
文件名包含一个 timestamp 以便排序(如果之前数据库没有被创建,那么 InitialCreate migration 将不会被创建,相反,当我们第一次调用 Add-Migration 的时候所有表都将归集到一个新的 migration 中)

多个实体锁定同一数据库
  当使用 EF6 之前的版本时,只会有一个 Code First Model 被用来生成/管理数据库的 Schema,
这将导致每个数据库只会有一张 __MigrationsHistory 表,从而无法辨别实体与模型的对应关系。
   从 EF6 开始,Configuration 类将会包含一个 ContextKey 属性,它将作为每一个 Code
First Model 的唯一标识符, __MigrationsHistory 表中一个相应地的列允许来自多个模型(multiple models)的实体共享表(entries),默认情况下这个属性被设置成 context 的完全限定名。

生成、运行迁移
  Code First Migrations 有两个你需要熟悉的命令:

Add-Migration 将 scaffold 创建下一次基于上一次迁移以来的更改的迁移;
Update-Databse 将任何挂起的迁移应用到数据库

  我们需要脚手架(scaffold 直译)一个迁移,以上面的 Url 属性为例,命令 Add-Migration 允许我们对迁移命名,我们姑且称之为 AddBlogUrl

在 Package Manager Console 中运行命令 Add-Migration AddBlogUrl;
一个新的迁移(名称包含 timestamp 前缀)在目录 Migrations 中创建成功





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

public partial class AddBlogUrl : DbMigration
{
public override void Up()
{
AddColumn("dbo.Blogs", "Url", c => c.String());
}

public override void Down()
{
DropColumn("dbo.Blogs", "Url");
}
}
}


  我们现在可以对这个迁移进行编辑或者增加,但似乎看起来还不错,那我们就直接用 Update-Database 来应用到数据库吧

在 Package Manager Console 中运行命令 Update-Database ;
AddBlogUrl 迁移将会被应用到数据库(表 Blogs 增加一列 Url)





定制化迁移
  到目前为止我们生成并运行了一个迁移,但是没有对迁移做任何更改,下面我们将尝试做一些更改:在类 Bolg 上增加一属性 Rating

public int Rating { get; set; }


  新建 Post

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; }
}


  在 Blog 中添加 Post 的集合

public virtual ICollection<Post> Posts { get; set; }


  在 Package Manager Console 中运行命令 Add-Migration AddPostClass
  生成的迁移如下



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

public partial class AddPostClass : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.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("dbo.Blogs", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId);

AddColumn("dbo.Blogs", "Rating", c => c.Int(nullable: false));
}

public override void Down()
{
DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
DropIndex("dbo.Posts", new[] { "BlogId" });
DropColumn("dbo.Blogs", "Rating");
DropTable("dbo.Posts");
}
}
}


  接下来我们对迁移做些更改:

在 Posts.Title 列上增加唯一索引;
使 Blogs.Rating 列非空,对于表中已经存在的数据,新列都会被赋值成 CLR 的默认数据类型(如 Rating 是整型,故默认值为0),但是我们想指定默认值为3,这样存在的记录将会有一个合理的评分。

  更改后的代码如下

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

public partial class AddPostClass : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.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("dbo.Blogs", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId)
.Index(p => p.Title, unique: true);

AddColumn("dbo.Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
}

public override void Down()
{
DropIndex("dbo.Posts", new[] { "Title" });
DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
DropIndex("dbo.Posts", new[] { "BlogId" });
DropColumn("dbo.Blogs", "Rating");
DropTable("dbo.Posts");
}
}
}


  在 Package Manager Console 中运行命令 Update-Database –Verbose





数据移动 / 定制SQL
  迄今为止,迁移都没有更改或移动数据,现在让我们看一下需要移动数据的例子。虽然没有对数据移动的原生支持,但是我们可以随意运行 SQL 脚本。
  让我们在 Post 中增加一个属性 Abstract, 稍后我们使用列 Content 的开头来填充此列(数据库已有记录)

public string Abstract { get; set; }


在 Package Manager Console 中运行命令 Add-Migration AddPostAbstract ;
生成的迁移非常好,但是我们想使用 Content 的前 100 个字符来预填充 Abstract 列,我们可对迁移做如下更改

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

public partial class AddPostAbstract : DbMigration
{
public override void Up()
{
AddColumn("dbo.Posts", "Abstract", c => c.String());
Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");
}

public override void Down()
{
DropColumn("dbo.Posts", "Abstract");
}
}
}


  在 Package Manager Console 中运行命令 Update-Database –Verbose

迁移至指定版本(包括后退)
  迄今为止,我们总是升级至最新迁移,然而某些时候我们需要升级/降级至指定版本,例如我们想迁移数据库至运行 AddBlogUrl 迁移之后的状态,此时我们就可以使用 –TargetMigration 来降级到这个版本
  在 Package Manager Console 中运行命令 Update-Database
–TargetMigration: AddBlogUrl



  这个命令将会运行 AddBlogAbstract and AddPostClass 的 Down 命令
  如果你想回滚一切至空数据库,可以使用命令 Update-Database –TargetMigration: $InitialDatabase



得到SQL脚本
  如果其它开发人员也希望在他们自己的机器上拥有这些更改,他们只需在我们 check in 代码至 source control 的时候做一次同步即可,一旦他们拥有了这些迁移,只需运行命令 Update-Database 就可以把这些更改应用于本地。但是如果我们想把这些更改推送至测试服务器或生产服务器,我们也许需要一份 SQL 脚本提供给 DBA

在运行 Update-Database 的时候指定 -Specify 标记,我们就能够使得这些更改被写入一个脚本中而不是被应用,我们同时也会为此脚本指定源迁移和目标迁移,例如我们希望产生的脚本是从一个空数据库($InitialDatabase)到最新的版本(AddPostAbstract 迁移);(注意:如果你没有指定目标迁移,那么迁移将始终更新至最新版本;如果你没有指定源迁移,那么迁移将以数据库目前状态为初始)
在 Package Manager Console 中运行命令 Update-Database
-Script -SourceMigration: $InitialDatabase -TargetMigration: AddPostAbstract



  产生的 SQL 脚本如下



DECLARE @CurrentMigration [nvarchar](max)

IF object_id('[dbo].[__MigrationHistory]') IS NOT NULL
SELECT @CurrentMigration =
(SELECT TOP (1)
[Project1].[MigrationId] AS [MigrationId]
FROM ( SELECT
[Extent1].[MigrationId] AS [MigrationId]
FROM [dbo].[__MigrationHistory] AS [Extent1]
WHERE [Extent1].[ContextKey] = N'MigrationsDemo.BlogContext'
)  AS [Project1]
ORDER BY [Project1].[MigrationId] DESC)

IF @CurrentMigration IS NULL
SET @CurrentMigration = '0'

IF @CurrentMigration < '201312240822431_InitialCreate'
BEGIN
CREATE TABLE [dbo].[Blogs] (
[BlogId] [int] NOT NULL IDENTITY,
[Name] [nvarchar](max),
CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY ([BlogId])
)
CREATE TABLE [dbo].[__MigrationHistory] (
[MigrationId] [nvarchar](150) NOT NULL,
[ContextKey] [nvarchar](300) NOT NULL,
[Model] [varbinary](max) NOT NULL,
[ProductVersion] [nvarchar](32) NOT NULL,
CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey])
)
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201312240822431_InitialCreate', N'MigrationsDemo.BlogContext',  0x1F8B0800000000000400CD574B4FDB4010BE57EA7FB0F6D41EC826E1D22207040954511B4018B86FEC4958751FAE778D92DFD6437F52FF4267FD8E4D1E200EBD44F178E69B996FE7B1FEFBFB8F7FB692C27B86C470AD4664D0EB130F54A823AE962392DAC5D1177276FAF1837F19C995F758EA1D3B3DB45466449EAC8D4F2835E11348667A928789367A617BA19694459A0EFBFDAF7430A0801004B13CCFBF4B95E512B2077C1C6B15426C5326663A02610A39BE093254EF9A4930310B6144667C99308B519809484DBC73C11946118058108F29A56DF6F6E4C1406013AD96418C0226EED731A0DE82090345EC27B5FAA169F4872E0D5A1BBE8906522588295E221576EDC2CBD21C910BA1974D0DD4F90EEB0D018A6E131D4362D777B068D84D23E2D14D5BDA36AE4C5B762E8411992A7B3C24DE752A049B0BA8186B501B589DC03750800701D12DB3161264701A41964A2782963FF75B7AC323C24A23DE8CAD7E805ADA273C60B622DE155F41544A8A081E14C7C244239BA4B0CFC94322DED9874FEB93EA9E1F96B0651C296990EA64B0B2ADB3CCF503B00D4D43BC1A3C2FE65E56062F4650F9AAFB84E68D523614DDD251FE8CC53192D1E8B042E205797B8D8F82D797B4CC3168685EA8EC2ADACA13960F5B42EB2DBAC648AF7862EC84593667EE38C691ECA81DC06CE9A94970BB7F6ABE4B6DF73FB7D89C31BD6E433699BBC26424567E96175431BCD4C785611032C1922D5D38D622956A5747EF42C97BAB89914B0E47C81AA7099009BAF63E6DE5DF269876186ECDA5F671EDAAF4B64AE5BDAAF85665FB4595ED5F289DB2CB558887C43CF3C8955CB0361664CF29F4825F622C38E65B2BCC98E20B30F65EFF049C83C3FE60D8DA4B6FD811D49848FCCF8B823B0AF6AE82CE1E397C37A86796844F2CF924D9EA7313E995F3FF1538AF9BF1DD81B57FD26F1DF479D58D4834C74BCD7D1E60B11ADEB803BA1DE0D3E6C5CB9F80E1CB1AC25DC314846EEED5A0A5CE542D74493166D48CA854699DC00C2C8B9098F3C4F2050B2DBE0EC1986C153F3291A2CAA59C43345537A98D537B6E0CC8B9D8B83EF874B7FF6CD16DC6ECDFC4D9E47E8F14304C8E29C08DBA48B988AAB8AFBAA5BC0DC2D548D11F18155E45106EB9AE90AEB53A10A8A06F023128D75DF720638160E64605EC19B6C7B69FC34DC6FC0967B8FEA429306A7BF71D40DD87C0E93F1D45E2A93A0C0000 , N'6.0.2-21211')
END

IF @CurrentMigration < '201312310618077_AddBlogUrl'
BEGIN
ALTER TABLE [dbo].[Blogs] ADD 

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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();
}
}
}


原文:
http://msdn.microsoft.com/en-us/data/jj591621" target=_blank> [nvarchar](max)
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201312310618077_AddBlogUrl', N'MigrationsDemo.BlogContext', 0x1F8B0800000000000400CD574B4FDB4010BE57EA7FB0F6D41EC826E1D22207040954511B4018B86FEC4958751FAE778D92DFD6437F52FF4267FD8E4D1E200EBD44F178E69B996FE7B1FEFBFB8F7FB692C27B86C470AD4664D0EB130F54A823AE962392DAC5D1177276FAF1837F19C995F758EA1D3B3DB45466449EAC8D4F2835E11348667A928789367A617BA19694459A0EFBFDAF7430A0801004B13CCFBF4B95E512B2077C1C6B15426C5326663A02610A39BE093254EF9A4930310B6144667C99308B519809484DBC73C11946118058108F29A56DF6F6E4C1406013AD96418C0226EED731A0DE82090345EC27B5FAA169F4872E0D5A1BBE8906522588295E221576EDC2CBD21C910BA1974D0DD4F90EEB0D018A6E131D4362D777B068D84D23E2D14D5BDA36AE4C5B762E8411992A7B3C24DE752A049B0BA8186B501B589DC03750800701D12DB3161264701A41964A2782963FF75B7AC323C24A23DE8CAD7E805ADA273C60B622DE155F41544A8A081E14C7C244239BA4B0CFC94322DED9874FEB93EA9E1F96B0651C296990EA64B0B2ADB3CCF503B00D4D43BC1A3C2FE65E56062F4650F9AAFB84E68D523614DDD251FE8CC53192D1E8B042E205797B8D8F82D797B4CC3168685EA8EC2ADACA13960F5B42EB2DBAC648AF7862EC84593667EE38C691ECA81DC06CE9A94970BB7F6ABE4B6DF73FB7D89C31BD6E433699BBC26424567E96175431BCD4C785611032C1922D5D38D622956A5747EF42C97BAB89914B0E47C81AA7099009BAF63E6DE5DF269876186ECDA5F671EDAAF4B64AE5BDAAF85665FB4595ED5F289DB2CB558887C43CF3C8955CB0361664CF29F4825F622C38E65B2BCC98E20B30F65EFF049C83C3FE60D8DA4B6FD811D49848FCCF8B823B0AF6AE82CE1E397C37A86796844F2CF924D9EA7313E995F3FF1538AF9BF1DD81B57FD26F1DF479D58D4834C74BCD7D1E60B11ADEB803BA1DE0D3E6C5CB9F80E1CB1AC25DC314846EEED5A0A5CE542D74493166D48CA854699DC00C2C8B9098F3C4F2050B2DBE0EC1986C153F3291A2CAA59C43345537A98D537B6E0CC8B9D8B83EF874B7FF6CD16DC6ECDFC4D9E47E8F14304C8E29C08DBA48B988AAB8AFBAA5BC0DC2D548D11F18155E45106EB9AE90AEB53A10A8A06F023128D75DF720638160E64605EC19B6C7B69FC34DC6FC0967B8FEA429306A7BF71D40DD87C0E93F1D45E2A93A0C0000 , N'6.0.2-21211')
END

IF @CurrentMigration < '201312310648099_AddPostClass'
BEGIN
CREATE TABLE [dbo].[Posts] (
[PostId] [int] NOT NULL IDENTITY,
[Title] [nvarchar](200),
[Content] [nvarchar](max),
[BlogId] [int] NOT NULL,
CONSTRAINT [PK_dbo.Posts] PRIMARY KEY ([PostId])
)
CREATE INDEX [IX_BlogId] ON [dbo].[Posts]([BlogId])
CREATE UNIQUE INDEX [IX_Title] ON [dbo].[Posts]([Title])
ALTER TABLE [dbo].[Blogs] ADD [Rating] [int] NOT NULL DEFAULT 3
ALTER TABLE [dbo].[Posts] ADD CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201312310648099_AddPostClass', N'MigrationsDemo.BlogContext', 0x1F8B0800000000000400D558CD6EE33610BE17E83B083AB505D64AB29736B07791759222681D0751B2D78091C60E518A54452AB09F6D0F7DA4BE4287FA33454AB6ECAC17DD4B1093331F6786DF0C67F4EF977FC61F5709F35E219354F0897F3A3AF13DE09188295F4EFC5C2DDEFDEA7FFCF0E30FE3AB3859799F6BB9F75A0E35B99CF82F4AA5E74120A31748881C2534CA84140B358A4412905804672727BF05A7A70120848F589E37BECFB9A209143FF0E754F0085295133613313059ADE34E58A07AB7240199920826FE8C2E33A2D00A790989F0BD0B46095A11025BF81EE15CA862F7FC5142A832C197618A0B843DAC5340B90561122ADBCF37E243DD3839D36E041BC583C2E0370EA28B57180AB5D6E6156E4EFC4F4C2C4D0994F903D6AD055CBACB440A995ADFC3C2D0BB897D2F68EB06B672A36AE9691326FE0D57EFCF7CEF36678C3C336822668436542283DF81035E04C4774429C83082373114AE381658E7E9BFF5697845C834DF9B91D59FC097EA052F98AC7CEF9AAE20AE572A0B1E394562A292CA72D875C863C68E7EC63D8643036F0F9C85714B5EE9B288A3857627A492BE770FACA4F70B4D4B5A8FF4CE53C10AEF3A13C9BD609578B1F8F440B225283443D83BA1C8B3C832611C6C08B795861AE6101A6ABD436858EB7D2B1A3E50C5B6F110F3F52B70044B9B427B8ECEC561493C948B25D9F6A7624D38978A35498750F1424A11D1E268831B4F1D75F18AC75EAF0D65C06BAB31E63953346534C22327FE2F4E34BAC09ADCDA8095DEB7C14E7D3B2FE6FC121828F02EA2F27D99121991D8BD038C41DC5EC154824C739830648F5419A15CB97947794453C2FA4CB614F67831B4510DBCBD730929709D617D717FDBB90DBC15A45D3119070669DCB2A6B3103520330C2832736597B8523E0465486255DE10B5C50287416DE5AAA43BCA251F2D65C3813642956FC6BE938C761CB7E5456364639F730DDB32C150AF626313BAED4847BE37B7B1E9F382B2D1AB1BC2A0A7231CCF489A6201353AC46AC50BCBF670FA2EDCBF254B4A8C20921D9D59636D7312BE3B6409D6AE2EF5315CD34CAA4BA2C833D1F5761A278ED800EED527991474EFA826552DADFF2F35DA3DF2A88B229BC85DA333894EE8E23DB5AED7552B9A72C248D6F3004D05CB13BE3DCFFB51CADED0C428578623148D9F09502C0CD7AF9B3A13A25E7351C6811545A7A239F7E494FFF6A50FA24499B86FA084DBDC0DA244B75A5F28EB8ECE0C657777B80DA5EAD34C906A693846D3859928CDE2709CFD487E547238C5D416694E6F8AAA553CC75521DB3D733B95AD14F13D0CCF2B8D75550BD7524132D202A3F06F3665B4086D2D30239C2E40AA07F11770DD5B9F9E59A3FB0163742065CCFECFB334D521D839A6ECEAD2B78CCFFC9564D10BC97E4AC8EA671369CF11F94D38ED31B8F079AB4BDFC9047A94CB6B0D9D75D4DDB173BF0BB066CC375D6607810FBACC4366B8B2CFFD96A356BBD13D60663C6856EBE9C78E369F7D1F3399DB3EEF9ECC7A07B3F2819AF8F1B3C05B2DD9DB3DAE74CD6CBD235B176CE71075A469CEF479D3A3EF1AE09C99EF38339BDB4E20478C0FFDC84D49971B08FDD99F43D462472373C317A226A965512D6255AE19281223752E3245172452B81D8194C5D3F499B01C45AE9267886FF83C5769AED065489E59EB3BA126FBB6F38BC1B46DF3789E166DF5D77001CDA4E802CCF9A79CB2B8B1FBBAA3EEF640E82CAADE2B7D974ABF5BCB7583742BF840A02A7C4DF23F4092320493731E9257E8B76D770CDB111B5F5282B349222B8C8D3EFE44FAC5C9EAC37FEC5F9589AA1A0000 , N'6.0.2-21211')
END

IF @CurrentMigration < '201312310729575_AddPostAbstract'
BEGIN
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201312310729575_AddPostAbstract', N'MigrationsDemo.BlogContext', 0x1F8B0800000000000400D559CD6EE33610BE17E83B083AB505D64AB29736B077E1759222689D0451B2D78096C636518A54452AB09F6D0F7DA4BE4287FA1729D9B2B35E742F414CCE7C9C197E339CB1FFFDF2CFF8E32662CE2B24920A3E71CF4767AE033C1021E5AB899BAAE5BB5FDD8F1F7EFC617C1D461BE77329F75ECBA126971377AD547CE97932584344E428A24122A458AA5120228F84C2BB383BFBCD3B3FF700215CC4729CF163CA158D20FB801F67820710AB94B0B90881C9621D77FC0CD5B92311C898043071E77495108556C82B8884EB4C192568850F6CE93A8473A1B2DDCB6709BE4A045FF9312E10F6B48D01E5968449286CBFACC587BA7176A1DDF06AC5A3C2E0560EA28BD7180AB5D5E6656E4EDC4F4CAC9A1228F3076C5B0BB8F490881812B57D846543EF36741DAFADEB99CA95AAA1A74D98B8B75CBDBF709DBB9431B2605045AC115A5F89047E070E7811103E10A520C108DE8690B96259609CA7FF96A7E11521D35C674E367F025FA9355E30D9B8CE0DDD4058AE14163C738AC4442595A4B0EF90E7849DFC8C470C8706DE1D3803E38EBCD255164703ED4148255DE711584EEF358D735A8FF4CE4BC60AE72611D1A3608578B6F8F2449215283443983BBE4893C03061ECD584DB49430D730C0DB5DE31342CF5BE150D9FA862BB7888F9FA153882A54DA13D27E7E27421554282D31F34AC5A0C257DCEEAC3395F32DBE67C990D43383F955204343BBA41C2978E027CCD43A7D7863CE0A5D518F394291A331AE09113F7172B1A5D605512D760B9F76DB073D74CC07B7E050C1438D3207FC866440624B4EF006310B657306721D1C94218D254F38772652738E5018D09EB33D95038E069D24655F0E6CE15C4C0752AF7C5FD6DE756F04690F6C564EC354863D74F9DEEA80149C380AC046CCC5A9ACBFBA01A9258FE6BA2B6586031A8AD5CBC1D9672CE4743B9E1401BA1C8B7C6BE958C661C77E5456564659F750DBB32A1A15EC4C62474DB918E7CAF6EA36E28BDBCA32C3B4FAFA7F51CCF491C63016DB4A2C58AE3E77DE8EC9D7F78EF17E5185E203B5AC0CADAEA247CE0C80A8C5DFDA684704313A9AE88220BA2EBED2C8C2CB101DC2B4F6A52D0BEA39254A5B4FE3FD76837E3A32E8AD491BB4167229DD0D9C36D5CAFAD9675FF8491A4E7019A0996467C779EF7A3E44D6813235F198E9075984D806C61B87ED93D3621CA351B65EC1951B42A9A754F56F96F5FFA204AE489FB064AD85DE4204A74ABF585B26C1D9BA1EC6E4377A1140D6113A4581A8E51B57B4D946A71384EDDCE3581EAD5E14887A5CB496966956553A43ABD2ACF46191E172571FFD704568DCC455C07C3F34A435D1FFDAD54108DB4C0C8FF9BCD18CD2EA91498134E9720D593F80BB81E07CE2F8C6F1B8E98FC3D2943F67F1EFFA90EC1DEC96A5FBFBF63E2E7AF2409D624F929229B9F9B48074EF56FC2694FEE99CF3B5DFA4E86E6935C5E6B4E2EA36E4FCA875D803116BFE932CDD1F74D601DD97014338E192DF3F6FB5B4E80EDFEFB8851F6A811B2A74D3CD9D8F87D8C8A7657BF7F60EC9D17F3D76EE2860B81B79AB3B77B8AEA1A257B27C92ED8CED9EE444366D3E77A74D837575AA3E8694649BB37418E347EE8406E4ABAAA21F4CF1E1C82163B2A995BBE1425490D8B4A11A372CD419110A9334D145D6239C4ED00A4CCDEB9CF84A528721D2D20BCE5F7A98A53852E43B460ADEF4935D9779D9FCDCB6D9BC7F771D6ED7F0D17D04C8A2EC03DFF9452165676DF74D4DD1E089D45C5E3A7EF52E94770B5AD90EE041F085484AF4AFE2788628660F29EFBE415FA6DDB1FC376C4C65794E0C814C902A3D6C78F48BF30DA7CF80FF7E621BAAA1B0000 , N'6.0.2-21211')
END[/code]

产生幂等脚本(EF6+)
  从 EF6 开始,如果你使用 –SourceMigration $InitialDatabase, 产生的脚本将是幂等的,幂等脚本意味着无论数据库当前处于什么版本/状态,都能升级至最新版本或指定版本(指定 –TargetMigration),生成的脚本包括检查表 __MigrationsHistory 的逻辑以及只更新之前从未更新的

在应用程序启动时自动升级(MigrateDatabaseToLatestVersion初始化器)
  当你发布部署应用程序的时候,可能希望当程序启动的时候它自动更新数据库(更新应用任何未更新的迁移),你可以通过注册 MigrateDatabaseToLatestVersion 数据库初始化器来实现这一点,数据库初始化器只包含一些逻辑检查用于确保数据库被正确设置,这个逻辑检查将会在AppDomain 的 context 第一次被使用的时候执行。
  当我们创建一个初始化器的实例时,需要指定 context type(BlogContext)以及 migrations
configuration (Configuration)- 这个迁移配置类是在我们启用迁移时生成的 Migrations 目录下增加的



using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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();
}
}
}


原文:[url=http://msdn.microsoft.com/en-us/data/jj591621]http://msdn.microsoft.com/en-us/data/jj591621


作者:[url=http://panchunting.cnblogs.com/]舍长
出处:http://panchunting.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

分类: [14] Entity Framework

标签: Code First, Entity
Framework, Migrations

好文要顶 关注我 收藏该文








舍长

关注 - 5

粉丝 - 194

+加关注

16

0

(请您对文章做出评价)

« 上一篇:Entity
Framework Code First (七)空间数据类型 Spatial Data Types

» 下一篇:使用sp_executesql

posted @ 2013-12-31 16:42 舍长 阅读(13114)
评论(9) 编辑 收藏

评论列表

#1楼2014-01-01
22:31 水木年华

<img src="http://images.cnitblog.com/blog/127185/201401/01222551-03ef3119fc394a4ebe873b037a811b7c.jpg" alt="" border="0" "="" style="margin: 0px; padding: 0px; border: 0px; max-width: 400px;">

大侠,请问这个是什么原因呢。我用的EF5.0的
支持(1)反对(0)

#2楼2014-07-25
14:42 摆渡人的歌

写的不错,看了一遍就明白了,EF6的Migration功能真是非常强大。
支持(0)反对(0)

#3楼2014-12-13
23:53 人生无赖

EF他把所有的实体变化记录下来这点我比较不喜欢,我觉得实体变化之后,Nh中,我们的做法都是直接生成当前数据库和Model差异的SQL去数据库跑一下就好了,EF就不行。
支持(0)反对(0)

#4楼2014-12-19
00:04 NiuSys

EF还是太折腾啊, 有了NH的SchemExport我们再也不当心更新数据库的问题了
支持(0)反对(0)

#5楼2015-09-07
15:12 czzjw

good
支持(0)反对(0)

#6楼2015-10-08
22:07 wuball

Update-Database提示已存在表,怎么解决啊?

必须要手动删除数据库吗?
支持(0)反对(0)

#7楼2015-10-23
13:24 ahdung

请教博主,我在数据库新增了一张表,如何添加一个model到Models目录中,前提是我已经用【code first from database】生成了Context类和若干model类,现在只不过是想从db新增一个model,当然不能是手写cs,并且能自动向context中新增该model的DbSet<T>属性。

另外有方法能自动批量为每个model生成Controller吗?
支持(0)反对(0)

#8楼2015-11-21
10:42 #张志豪#

写的很吼啊,对我帮助很大,谢谢!
支持(0)反对(0)

#9楼2016-03-10
16:09 勇打痘痘

写的很清晰,非常不错的一篇文章
支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库

【推荐】融云即时通讯云-豆果美食、Faceu等亿级APP都在用





最新IT新闻:

· Google Calendar上线“Find a Time”会议功能

· 新型液态金属微粒让室温下的无热焊接成为了可能

· GNU编译器套件GCC 6.1发布 默认使用C++14标准

· 微软将测试DNA数据存储:每克材料能存10亿TB

· 任天堂本财年将发布两款新手游 可惜仍没有超级玛丽

» 更多新闻...





最新知识库文章:

· 架构漫谈(九):理清技术、业务和架构的关系

· 架构漫谈(八):从架构的角度看如何写好代码

· 架构漫谈(七):不要空设架构师这个职位,给他实权

· 架构漫谈(六):软件架构到底是要解决什么问题?

· 架构漫谈(五):什么是软件

» 更多知识库文章...


公告

昵称:舍长

园龄:7年1个月

粉丝:194

关注:5
+加关注

<2016年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567


搜索


常用链接

我的随笔

我的评论

我的参与

最新评论

我的标签

更多链接


我的标签

Code First(9)

Entity Framework(8)

SQL Server(8)

SQL Server 2008 R2(4)

Quartz.net(4)

IIS(4)

JavaScript(3)

Android(3)

ASP.NET(3)

C#(2)

更多


随笔分类(69)

[01] Algorithm(3)

[02] Android(3)

[03] ASP.NET(8)

[04] C#(6)

[05] IIS(2)

[06] JavaScript&jQuery(5)

[07] Log4net(1)

[08] Quartz.Net(5)

[09] Scala(1)

[10] SQL Server(15)

[11] NoSQL(2)

[12] Unity(2)

[13] MVC(1)

[14] Entity Framework(9)

[15] Python

[16]VBScript(1)

[17] HTML5(1)

[18] Cloud(1)

[19] RESTful(1)

[20] SignalR(2)


随笔档案(66)

2015年12月 (1)

2015年5月 (1)

2015年4月 (3)

2015年3月 (4)

2014年12月 (1)

2014年11月 (1)

2014年10月 (3)

2014年9月 (1)

2014年8月 (1)

2013年12月 (11)

2013年11月 (2)

2013年9月 (2)

2013年7月 (5)

2013年6月 (1)

2013年5月 (2)

2013年4月 (7)

2012年8月 (1)

2012年6月 (2)

2012年4月 (1)

2011年10月 (2)

2011年9月 (3)

2011年7月 (1)

2011年5月 (2)

2011年2月 (3)

2010年12月 (1)

2010年4月 (1)

2010年3月 (3)


最新评论

1. Re:MVC5 + EF6 简单示例

这个数据库不是在本地吗???

--x朱

2. Re:MVC5 + EF6 简单示例

出现19楼问题的可以先把代码能够编译,先不添加控制器,能够运行看到默认页面,再试试。

有可能是拷贝Web.Config中entityFramework结出现的问题了。

--咸鱼翻身

3. Re:MVC5 + EF6 简单示例

同19楼一眼的问题,如何解决啊

--oceanwind

4. Re:Entity Framework Code First (八)迁移 Migrations

写的很清晰,非常不错的一篇文章

--勇打痘痘

5. Re:MVC5 + EF6 简单示例

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Data.E......

--靖舞


阅读排行榜

1. MVC5 + EF6 简单示例(46044)

2. Entity Framework Code First (八)迁移 Migrations(13114)

3. SQL Server系列之 删除大量数据(12533)

4. Entity Framework Code First (六)存储过程(11994)

5. Entity Framework Code First (一)Conventions(10116)


评论排行榜

1. MVC5 + EF6 简单示例(36)

2. Entity Framework Code First (六)存储过程(11)

3. Quartz.Net 学习随手记之02 简单示例(10)

4. Entity Framework Code First (八)迁移 Migrations(9)

5. Entity Framework Code First (一)Conventions(9)


推荐排行榜

1. Entity Framework Code First (八)迁移 Migrations(16)

2. Entity Framework Code First (一)Conventions(11)

3. Entity Framework Code First (四)Fluent
API - 配置属性/类型(11)

4. Entity Framework Code First (三)Data Annotations(10)

5. Entity Framework Code First (二)Custom Conventions(10)

Copyright ©2016 舍长
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: