当EF4.3数据库迁移遭遇Timestamp(解决方案)
EF4.3终于向完美的数据库迁移迈出了重要一步,决定在新项目中使用EF4.3。
问题发生了。
按照 step by step 来没问题,当我第二个迁移为实体增加了一个timestamp时:
/// <summary>
/// 行时间戳
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public byte[] Timestamp { get; set; }
在NUGET控制台执行
Add-Migration U3
执行成功
生成的更新代码为:
namespace TFFY.Models.Migrations
{
using System.Data.Entity.Migrations;
public partial class U3 : DbMigration
{
public override void Up()
{
AddColumn("Tickets", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
AddColumn("TicketItems", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
AddColumn("TicketItemPackages", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
AddColumn("TicketPayments", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
AddColumn("Users", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
AddColumn("Products", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
}
public override void Down()
{
DropColumn("Products", "Timestamp");
DropColumn("Users", "Timestamp");
DropColumn("TicketPayments", "Timestamp");
DropColumn("TicketItemPackages", "Timestamp");
DropColumn("TicketItems", "Timestamp");
DropColumn("Tickets", "Timestamp");
}
}
}
当继续执行更新数据库时
PM> Update-Database -Verbose Using NuGet project 'TFFY.Models'. Using StartUp project 'TFFY.Models.Test'. Target database is: 'TFFYDBContext' (DataSource: ., Provider: System.Data.SqlClient, Origin: Convention). Applying explicit migrations: [201203070939136_U3]. Applying explicit migration: 201203070939136_U3. ALTER TABLE [Tickets] ADD [Timestamp] rowversion NOT NULL DEFAULT 0x System.Data.SqlClient.SqlException (0x80131904): 不能在数据类型为 timestamp 的列上创建默认值。表 'Tickets',列 'Timestamp'。 无法创建约束。请参阅前面的错误消息。 在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 在 System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 在 System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 在 System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 在 System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading) 在 System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 在 System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 在 System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 在 System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 在 System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 在 System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 在 System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore() 在 System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 不能在数据类型为 timestamp 的列上创建默认值。表 'Tickets',列 'Timestamp'。 无法创建约束。请参阅前面的错误消息。
看,悲剧发生了。。。
问题显然在于 rowversion NOT NULL DEFAULT 0x
我的临时解决方法
AddColumn("Tickets", "Timestamp", c => c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"));
//把迁移生成代码 相应字段 的 nullable: false 改成 nullable: true
AddColumn("Tickets", "Timestamp", c => c.Binary(nullable: true, fixedLength: true, timestamp: true, storeType: "rowversion"));
这样迁移过程中构建迁移sql语句时就会忽略关于默认值的设置
这样生成的数据库虽然把可null设为真,但数据库里生成的时间戳字段仍然为NOT NULL。

浙公网安备 33010602011771号