【发布时间】:2012-05-06 22:32:28
【问题描述】:
我正在使用 EF 4.3.1 迁移,并且我有 Configuration 类,其中包含以下代码:
internal sealed class Configuration : DbMigrationsConfiguration<DbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(PayByPhoneDbContext context)
{
context.Roles.AddOrUpdate(r => r.Name, new Role { Name = "A" }, new Role { Name = "B" });
context.Administrators.AddOrUpdate(a => a.Email, new Administrator { Email = "a@a.com" Name = "A", Role = context.Roles.Local.SingleOrDefault(role => role.Name == "A") });
}
}
现在,当我在数据库不存在时运行迁移命令(MSBuild 脚本的一部分)时,会创建表并按预期进行播种。但是,当我在没有任何迁移的现有数据库上运行 migrate 命令并且所有数据都已经播种时(当需要更新而不是插入时)我在运行 migrate 命令时遇到错误:
没有挂起的显式迁移。
运行种子方法。
System.Data.Entity.Infrastructure.DbUpdateException:发生错误 在更新条目时。有关详细信息,请参阅内部异常。 ---> System.Data.UpdateException:更新时出错 条目。有关详细信息,请参阅内部异常。 ---> System.Data.SqlClient.SqlException:UPDATE 语句冲突 具有 FOREIGN KEY 约束“FK_Administrators_Roles_RoleId”。这 数据库“xxxDB”、表“dbo.Roles”、“Id”列中发生冲突。
语句已终止。
堆栈跟踪:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
--- End of inner exception stack trace ---
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
--- End of inner exception stack trace ---
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
运行SQL Server profiler发现执行时出错:
exec sp_executesql N'update [dbo].[Administrators]
set [RoleId] = @0
where ([Id] = @1)
',N'@0 int,@1 bigint',@0=0,@1=1
在 Seed 方法中使用外键播种数据的正确方法是什么?
【问题讨论】:
-
您是否检查过
context.Roles.Local.SingleOrDefault(role => role.Name == "A")返回的角色是否正确,而不是null? -
很难调试它,因为它在 Nuget 控制台或命令提示符中运行(使用 migrate.exe 时)。
-
我已经删除了我的答案,它没用。也许不支持更新关系。至少 Ladislav 提到了它:AddOrUpdate 不支持以任何方式更改关系,因此您不能使用它在下一次迁移中添加或删除关系。(来自这里:stackoverflow.com/a/8551511/270591。答案来自 EF迁移预览阶段,但也许它仍然有效。)
标签: entity-framework-4.3 entity-framework-migrations