重新初始化代码首先创建的表,但将现有表数据保留在 entity framework 6

reinitialize code first created tables, but leave existed tables data on place with entity framework 6

假设我有 10 个实体。其中 8 个是全新的,使用 EF Code-first 方法构建。所以在我使用 DropCreateDatabaseIfModelChanges 初始化策略之前,这对我来说非常有效。

但现在我有 2 个实体,它们是基于一些第 3 方数据从数据库构建的,我一直需要这些数据,我不能允许 EF 删除这个 tables,即使模型改变了.我需要一些更智能的东西。

在那种情况下哪种方法是正确的?


简而言之,我想要非常相似的东西。我只需要 DbInitializer 行为,但基于 table,而不是基于数据库。我不希望 Code-first 实体像以前一样工作,重新生成和所有这些东西。但是只为这个特定的基于 2 数据库的实体添加一些自定义的东西。

你可以使用 EF Code First Migrations

首先,您需要在程序包管理器控制台中 运行 Enable-Migrations 命令。此命令将向我们的项目添加一个 Migrations 文件夹。这个新文件夹包含 Configuration class 允许您配置迁移在您的上下文中的行为方式。

现在,在那之后,如果您遵循了 要求的 步骤,您可以从 "Package Manager Console" 运行 "update database" 并添加八个新 tables 到您的数据库:

示例:

  1. 在您的模型中进行更改(添加八个新实体)
  2. 来自包管理器控制台:运行 添加迁移 [迁移名称]
  3. 对生成的代码进行任何必要的更改(这是可选的)。
  4. 来自包管理器控制台:运行 更新数据库

如果您不更改或删除与现有实体相关的任何 属性,则不应丢失数据库中已有的数据。

更新

要实现您想要的效果,您可以使用 Automated Migration。这样,当您 运行 您的应用程序时,您将始终获得最新版本的数据库,因为 EF 会在每次需要时进行隐式迁移 - 在最纯粹的版本中,您只需启用自动迁移即可。

首先,您需要使用新的数据库初始化策略 MigrateDatabaseToLatestVersion 在上下文 class 中设置数据库初始化程序,如下所示:

   public class YourContext: DbContext 
   {
        public YourContext(): base("DefaultConnectionString") 
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourContext, YourProject.Migrations.Configuration>("DefaultConnectionString"));    
        }
   }

稍后,在 Configuration class 的构造函数中,您必须启用自动迁移:

  public Configuration()
  {
    AutomaticMigrationsEnabled = true;
  }

现在,如果您正在使用现有数据库,在添加新的八个实体之前,您需要先执行以下操作:

  1. 运行中的Add-Migration InitialCreate –IgnoreChanges命令 包管理器控制台。这将创建一个空迁移 当前模型作为快照。
  2. 运行 程序包管理器控制台中的 Update-Database 命令。这个 会将 InitialCreate 迁移应用到数据库。自从 实际迁移不包含任何更改,它只会添加一个 到 __MigrationsHistory table 的行表示此迁移 已经应用了。

之后,您可以将您想要的更改应用到您的模型(例如,添加新的八个实体),当您再次执行您的应用程序时,EF 将为您进行迁移。

万一你要改变 某些事情会引起与您的数据库不一致的情况 模式,它可能会导致数据丢失,将抛出异常。 如果没有抛出这个异常,就不用担心丢失 您的数据,它将在您的数据库中保持完整。

作为附加信息,如果您不介意丢失您的数据(我认为这不是您的场景,但无论如何了解它都是有用的),您可以在 true 中设置 AutomaticMigrationDataLossAllowed 属性(其默认值为 false),如果您在执行迁移时要丢失数据库中的某些数据,则不会抛出异常。

public Configuration()
{
    AutomaticMigrationsEnabled = true;
    AutomaticMigrationDataLossAllowed=true;
}