重新初始化代码首先创建的表,但将现有表数据保留在 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 到您的数据库:
示例:
- 在您的模型中进行更改(添加八个新实体)
- 来自包管理器控制台:运行 添加迁移 [迁移名称]
- 对生成的代码进行任何必要的更改(这是可选的)。
- 来自包管理器控制台:运行 更新数据库
如果您不更改或删除与现有实体相关的任何 属性,则不应丢失数据库中已有的数据。
更新
要实现您想要的效果,您可以使用 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;
}
现在,如果您正在使用现有数据库,在添加新的八个实体之前,您需要先执行以下操作:
- 运行中的
Add-Migration InitialCreate –IgnoreChanges
命令
包管理器控制台。这将创建一个空迁移
当前模型作为快照。
- 运行 程序包管理器控制台中的
Update-Database
命令。这个
会将 InitialCreate 迁移应用到数据库。自从
实际迁移不包含任何更改,它只会添加一个
到 __MigrationsHistory table 的行表示此迁移
已经应用了。
之后,您可以将您想要的更改应用到您的模型(例如,添加新的八个实体),当您再次执行您的应用程序时,EF 将为您进行迁移。
万一你要改变
某些事情会引起与您的数据库不一致的情况
模式,它可能会导致数据丢失,将抛出异常。
如果没有抛出这个异常,就不用担心丢失
您的数据,它将在您的数据库中保持完整。
作为附加信息,如果您不介意丢失您的数据(我认为这不是您的场景,但无论如何了解它都是有用的),您可以在 true
中设置 AutomaticMigrationDataLossAllowed
属性(其默认值为 false
),如果您在执行迁移时要丢失数据库中的某些数据,则不会抛出异常。
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed=true;
}
假设我有 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 到您的数据库:
示例:
- 在您的模型中进行更改(添加八个新实体)
- 来自包管理器控制台:运行 添加迁移 [迁移名称]
- 对生成的代码进行任何必要的更改(这是可选的)。
- 来自包管理器控制台:运行 更新数据库
如果您不更改或删除与现有实体相关的任何 属性,则不应丢失数据库中已有的数据。
更新
要实现您想要的效果,您可以使用 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;
}
现在,如果您正在使用现有数据库,在添加新的八个实体之前,您需要先执行以下操作:
- 运行中的
Add-Migration InitialCreate –IgnoreChanges
命令 包管理器控制台。这将创建一个空迁移 当前模型作为快照。 - 运行 程序包管理器控制台中的
Update-Database
命令。这个 会将 InitialCreate 迁移应用到数据库。自从 实际迁移不包含任何更改,它只会添加一个 到 __MigrationsHistory table 的行表示此迁移 已经应用了。
之后,您可以将您想要的更改应用到您的模型(例如,添加新的八个实体),当您再次执行您的应用程序时,EF 将为您进行迁移。
万一你要改变 某些事情会引起与您的数据库不一致的情况 模式,它可能会导致数据丢失,将抛出异常。 如果没有抛出这个异常,就不用担心丢失 您的数据,它将在您的数据库中保持完整。
作为附加信息,如果您不介意丢失您的数据(我认为这不是您的场景,但无论如何了解它都是有用的),您可以在 true
中设置 AutomaticMigrationDataLossAllowed
属性(其默认值为 false
),如果您在执行迁移时要丢失数据库中的某些数据,则不会抛出异常。
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed=true;
}