使用 EF Core 2.0 迁移更新具有新列的表



我是EF Core的新手,一直在学习在线课程和一本书。我创建了数据库上下文并使用dotnet ef migrations add init后跟dotnet ef database update,一切都让我非常高兴。我在模型中添加了一个新列,并创建并应用了新的迁移,但遇到了:

> Applying migration '20180417175820_AddOsTypeColumn'.
Failed executing DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [MachineTypes] (
[MachineTypeID] int NOT NULL IDENTITY,
[Description] varchar(15) NULL,
CONSTRAINT [PK_MachineTypes] PRIMARY KEY ([MachineTypeID])
);
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'MachineTypes' in the database.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInA
ction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrap
CloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectio
nLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, B
ulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean as
yncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, In
t32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbComma
ndMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection,
IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadO
nlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migration
Commands, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String c
ontextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:09aa3af2-6ce8-4331-a586-c79841f4e1b6
Error Number:2714,State:6,Class:16
There is already an object named 'MachineTypes' in the database.

我看了这篇文章 在实体框架核心中使用更新数据库添加新列,它与我的初始问题相同,但提供的唯一解决方案并不适合我的情况; 我的日志表明它正在应用正确的迁移,但随后尝试创建一个现有表,就好像它正在运行 init 迁移一样。

由于它只是一个实践/学习数据库,我将其从SQL Server中删除并重新开始。这一次,按照上述步骤按预期工作。这次我知道的唯一区别是添加新列/新迁移时我没有连接到数据库。会是原因吗?

这次我知道

的唯一区别是添加新列/新迁移时我没有连接到数据库。会是原因吗?

我认为你在这里混淆了术语。添加新列是对数据库的操作;添加新迁移是对项目执行的操作。

在不连接到数据库的情况下更新数据库是不可能的,所以我假设您正在谈论更改模型/添加迁移。EF 不会为此查看任何数据库,因此没有。

澄清(假设代码优先方法)

创建迁移(添加迁移)时,EF 将查看以下两项内容:

  • 您的DbContext 类,用于确定数据库需要具有的完整架构
  • 迁移类,用于确定需要应用于数据库的(增量)架构(以及要为新迁移生成的代码)

应用迁移(更新数据库)时,EF 将查看以下两项内容:

  • 现有数据库的迁移历史记录表(如果存在且有),用于确定已应用哪些迁移
  • 迁移
  • ,以查看是否有任何尚未应用的迁移

因此,当您收到发布的错误时,这意味着:

  • 第二次迁移是在没有 EF 的情况下创建的,同时考虑到现有迁移(你更改了两者之间的命名空间,指向错误的迁移文件夹等)
    • 新迁移包括对旧迁移的更改
  • 您在已应用一个或多个迁移的数据库上调用了更新,但没有(正确的)迁移历史记录
    • 多次应用相同的迁移

最新更新