当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。

 

posted @ 2012-03-07 17:50  BinSys  阅读(2115)  评论(0编辑  收藏  举报