实体框架4.1自定义数据库初始化策略

时间:2011-07-16 21:29:04

标签: entity-framework-4.1 ef-code-first code-first

我想实现自定义数据库初始化策略,以便我可以:

  • 生成数据库(如果不存在)
  • 如果模型更改仅创建新表
  • 如果模型更改仅创建新字段而不删除表并丢失数据。

提前致谢

3 个答案:

答案 0 :(得分:2)

您需要实施IDatabaseInitializer界面。

例如

public class MyInitializer : IDatabaseInitializer<MyDbContext>
{
    public void InitializeDatabase(MyDbContext context)
    {
        //your logic here
    }
}

然后在应用程序启动时设置初始化程序

Database.SetInitializer<ProductCatalog>(new MyInitializer());

这是example

您必须手动执行命令才能更改数据库。

context.ObjectContext.ExecuteStoreCommand("ALTER TABLE dbo.MyTable ADD NewColumn VARCHAR(20) NULL");

您可以使用SQL Compare之类的工具编写更改脚本。

答案 1 :(得分:2)

有一个原因尚不存在。它非常复杂,而且IDatabaseInitializer接口并没有为此做好准备(没有办法使这种初始化数据库不可知)。您的问题“太宽泛”,无法满足您的要求。你对@ Eranga的正确答案的反应你只是希望有人会告诉你如何做到这一点,但我们不会 - 这将意味着我们将为你编写初始化器。

你需要做什么你想做什么?

  • 您必须非常了解SQL Server。您必须知道SQL Server如何存储有关数据库,表,列和关系的信息=您必须了解sys个视图,并且必须知道如何查询它们以获取有关当前数据库结构的数据。
  • 你必须非常了解EF。您必须知道EF如何存储映射信息。您必须能够探索元数据获取有关预期表,列和关系的信息。
  • 一旦您拥有旧的数据库描述和新的数据库描述,您必须能够编写一个代码,该代码将正确地探索更改并创建用于更改数据库的SQL DDL命令。即使这看起来像整个过程中最简单的部分,这实际上是最困难的部分,因为SQL服务器中有许多其他内部规则,您的命令不能违反这些规则。有时你真的需要删除表来进行更改,如果你不想丢失数据,你必须先将它们推送到临时表,然后在重新创建表之后你必须将它们推回去。有时您正在对约束进行更改,这可能需要暂时关闭约束等。有充分理由说,在SQL级别(比较两个数据库)上执行此操作的工具可能都是商业化的。

即使ADO.NET团队也没有实现这一点,他们将来也不会实现它。相反,他们正在开展一项名为迁移的工作。

编辑:

确实ObjectContext可以返回用于创建数据库的脚本 - 这正是默认初始值设定项正在使用的脚本。但它怎么能帮到你呢?您是否要解析该脚本以查看更改的内容?您是否要在另一个连接中执行该脚本以使用与当前数据库相同的代码来查看其结构?

是的,您可以创建一个新数据库,将数据从旧数据库移动到新数据库,删除旧数据库并重命名新数据库,但这是您可以想象的最愚蠢的解决方案,没有数据库管理员会允许这样做。即使这个解决方案仍然需要分析更改以创建正确的数据传输脚本。

自动升级是一种错误的方法。您应该始终使用某些工具手动准备升级脚本,对其进行测试,然后手动执行或作为某些安装脚本/包的一部分执行。您还必须备份数据库,然后才能进行任何更改。

答案 2 :(得分:2)

实现这一目标的最佳方法可能是迁移:

http://nuget.org/List/Packages/EntityFramework.SqlMigrations

好的博文herehere