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

  • 相关阅读:
    11月30日总结数据显示代码
    11月25日总结
    11月26日总结生成数据前端代码
    11月27日总结生成数据字典后端servlet层
    11月23日后端
    11月28日总结生成数据字典dao层
    11月29日生成数据字典damain层
    今日总结
    ARouter 在多 module 项目中实战
    ARouter 拦截器之多 module 独立运行
  • 原文地址:https://www.cnblogs.com/binsys/p/2383952.html
Copyright © 2020-2023  润新知