Entity Framework Code First Migrations:Alpha——第十周的NuGet包

Entity Framework Code First Migrations :Alpha——第十周的NuGet包

[原文发表地址] Entity Framework Code First Migrations: Alpha - NuGet Package of the Week #10

[原文发表时间] 2011-07-28 15:24

在发表关于我们的产品版本的RFC博文之后,Entity Framework团队接着发布了Entity Framework 4.1Code First Migrations:2011八月份CTP版本。酷。这也是七月的!

我更喜欢把这个产品命名为“Migrating Magic Unicorns 0.5”。也许最好把这个看做是EF的0.5 Alpha Migrations,但这只是我对名字的猜测,不能算是一种描述。

最近的一些会议中,我展示了EF Migrations的早期每日构建的版本,并鼓励大家给ADO.NET团队博客留言。现在他们提供了一些文件让我们自己尝试看看。这个初始版本的CTP能通过NuGetEntityFramework.SqlMigration包的形式获取。

EntityFramework.SqlMigrations - 0.5.10727.0

这就是大概的概念。注意这不是只针对Web的。您可以在控制台应用程序或者其它地方完成。我就喜欢Hello World Web应用程序。

简短演练

创建一个新的ASP.NET MVC应用程序,在引用中找到NuGet的管理包,并且搜索EntityFramework.SqlMigrations。请注意它的依赖项。它还会升级你的EntityFramework 项目包。

Entity Framework SQL Migrations In NuGet

现在,用一个简单模型生成一个新的类:

1

2

3

4

5

6

7

8

9

10

11

12

13

namespace MvcApplication15.Models

{

public class Person

{

public int PersonId { get; set; }

public string Name { get; set; }

}

public class DemoContext : DbContext

{

public DbSet<Person> People { get; set; }

}

}

快速搭建一个Person Controller。

Add Controller

通过/Person访问它,并生成一些People。

Index - Windows Internet Explorer (58)

生成的数据库如下图所示。有People表,而且第一列是个nvarchar类型。

image

现在我们来添加一个Email字段。我将修改Person类使其包含Email:

1

2

3

4

5

6

public class Person

{

public int ID { get; set; }

public string Name { get; set; }

public string Email { get; set; }

}

然后,我会编译,在Visual Studio的控制台里做以下工作:

PM> update-database
No pending custom scripts found.
Ensuring database matches current model.
- Performing automatic upgrade of database.
- Starting rebuilding table [dbo].[EdmMetadata]...
- Caution: Changing any part of an object name could break scripts and stored procedures.
- Starting rebuilding table [dbo].[People]...
- Caution: Changing any part of an object name could break scripts and stored procedures.
- Update complete.

我输入update-database,就完成了。这是一个自动的迁移。明白系统是如何比较.NET类型和数据库,并完成需要的工作了吧:

image

现在,我们把Email重命名为EmailAddress。如果我更新一下Person。

1

2

3

4

5

6

public class Person

{

public int ID { get; set; }

public string Name { get; set; }

public string EmailAddress { get; set; }

}

并输入update-database…

PM> update-database
No pending custom scripts found.
Ensuring database matches current model.
- Performing automatic upgrade of database.
Update-Database : - .Net SqlClient Data Provider: Msg 50000, Level 16, State 127, Line 6 Rows were detected. The schema update is terminating because data loss might occur.
At line:1 char:16
+ Update-Database <<<<
+ CategoryInfo : NotSpecified: (:) [Update-Database], Exception
+ FullyQualifiedErrorId : UnhandledException,System.Data.Entity.Migrations.Commands.MigrateCommand

有人跟我说可能会有数据丢失的情况。它不能分辨我到底是不是要把这一列重命名。不知道它之前是什么,也不确定之后会是什么。也许我想移掉Email添加EmailAddress?谁知道呢。让我说得简明扼要一点,解释更多关于Migrations的内容吧。

PM> Update-Database -Renames:"Person.Email=>Person.EmailAddress"
No pending custom scripts found.
Ensuring database matches current model.
- Performing automatic upgrade of database.
- The following operation was generated from a refactoring log file d5598498-a656-4ccd-1e93-bea562ab6e31
- Rename [dbo].[People].[Email] to EmailAddress
- Caution: Changing any part of an object name could break scripts and stored procedures.
- Update complete.

我不确定我喜不喜欢那样的重命名:句法。我相信团队会对你们的意见很感兴趣的。那的确可行,我在数据库中可以看到。

image

迁移可以自动检测到什么样的变化呢?

摘自ADO.NET博客:

这些是迁移可以自动检测到的所有变化:

  • 添加一个属性或者类
  • 对任意一行数据,可为空的列会被赋予一个空值
  • 对任意一行数据,不可为空的列会被赋予CLR默认的已给数据类型
  • 重命名属性或类
  • 参见“重命名属性和类”,了解更多需要的步骤
  • 不重命名属性/类来重命名栏/表(使用数据注释或流畅API)
  • 迁移可以无需额外的输入自动检测这些重命名
  • 移除属性
  • 参见“自动迁移及数据丢失”,了解更多信息。

移动到临时区/产品/等

一旦开发是正确的,想要转到生产环境时,你就要通过对比数据库和代码的不同为你其他的数据库生成一个脚本。

比如,脚本生成一个我自己可以通过osql.exe或者其他东西运行的脚本。

update-database -Script -ConnectionString "SERVER=.\SQLEXPRESS;Database=PersonProd;Trusted_Connection=true;"

它会列出这些东西(远比这些复杂):

CREATE TABLE [dbo].[People] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (MAX) NULL,
[EmailAddress] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC)
);

征求反馈

EF团队向大家征求自定义脚本相关的反馈信息

征求反馈:从我们内部的调试使用来看,我们觉得似乎不太会用到自定义脚本。但是我们的努力离不开现实世界的支持,所以我们需要你们的反馈来告诉我们你们在什么情况下需要用到自定义脚本。我们尤其想知道有没有这样的场景,就是要基于代码来写未经加工的SQL。

请在我的评论中告诉我们你的想法,或者他们的想法,我相信这些信息会发挥作用的。

希望你们喜欢!

附言:注意EntityFramework.SqlMigrations NuGet包发布的版本号是0.5.10727.0 ;)

局限性

这是Alpha,所以烦请阅读局限性部分。他们现在发布的是很粗浅的一些东西,因为他们知道我们想早点见到成果,但这会带来一些局限。这里提供一些,请查看列表获取更多信息。

  • 没有供应者模型,这次的发布只定位于SQL服务器,包括SQL Azure。不支持SQL Compact和其他供应者。我们现在还在研究迁移的供应者模型应该是什么样子的。问题:你的想法呢?这有多重要?
  • 迁移目前必须在完全信任的情况下运行。在Visual Studio中运行没有什么问题,但如果用自定义代码来使用迁移的话,你就要在中等信任模式下运行。我们正在想办法在下一次发布中解决这个问题。
  • 此次发布只能通过NuGet获取。随着我们支持更多的场景,比如团队建立和“Visual Studio外部”命令行,我们也会支持更多的安装选择。 Scott:局限性?真可爱 ;)
  • 目前还不支持降级,如果你生成自定义脚本,你就会发现脚本是被命名为“Up.sql”的,但没有“Down.sql”。我们准备在RTM之前添加降级功能,但在此次发布中还不行。

我很高兴我们有了迁移。这是一块缺失了很久的乐高积木呢。

相关链接