mysql datetimeoffset_针对Mysql 使用EF Code First时 TimeStamp/RowVersion 类型 的解决办法

环境:

mysql5.5

.Net Connector 6.6.4

EF 4.3.1

模型要求:

很多业务要求并发处理,时间戳是个很好的选择.

代码如下:

public class Test

{

public int ID { get; set; }

public string Name { get; set; }

public byte[] LastChanged { get; set; }

}

问题描述:在LastChanged属性用Data Annotations标记[Timestamp]

[Timestamp]

public byte[] LastChanged { get; set; }

或者Fluent API中配置成IsRowVersion()

DbModelBuilder 作如下配置

modelBuilder.Entity().Property(p => p.LastChanged).IsRowVersion();

或者EnityTypeConfiguration类中配置

Property(p=>p.LastChanged).IsRowVersion();

在Migration的时候 会有错误,如下:

错误 0040: 类型 rowversion 未使用命名空间或别名进行限定。只有 PrimitiveType 才可以在不限定的情况下使用。

原因是 MySqlMigrationSqlGenerator不允许byte[]类型上标记TimeStamp/RowVersion

那应该用什么类型?

database first来看看 这里就不截图 加表 设置字段类型 TIMESTAMP 默认值 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

生成EDM 类型 为Datetime 这和MsSql是有区别的

现在修改模型

public class Test

{

public int ID { get; set; }

public string Name { get; set; }

public DateTime LastChanged { get; set; }

}

编译下代码 不能通过 EF的.IsRowVersion()方法不能作用于DateTime类型的属性.

修改DbModelBuilder代码:

Property(p => p.LastChanged).IsConcurrencyToken();

再次Migration 并且 update-database 去查看数据库的表结构

问题又来了 LastChanged的数据库类型成Datetime了

我们手动来解决这个问题

修改DbMigration中的Up方法的代码

源代码如下:

AddColumn("Tests", "LastChanged", c => c.DateTime(nullable: false);

修改为

AddColumn("Tests", "LastChanged", c => c.DateTimeOffset(nullable: false, defaultValueSql: "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"));

update-database后 检查表结构 ok!没有问题了

测试下

using (var db = new BlogContext())

{

db.Tests.Add(new Test { Name = "Test01" });

db.SaveChanges();

}

是不是又异常了 看详细信息 原来把LastChanged字段的值更新回数据库了 这不是我们预期了

再去修改下DbModelBuilder代码:

Property(p => p.LastChanged).IsConcurrencyToken().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

再测试 ok! 通过

以上代码是成功后再添加的 如有问题 请指出

再来总结下mysql下使用code first时 时间戳类型 要注意的几点

1.模型中的类型 必须为datetime

2.使用IsConcurrencyToken()方法

3.up脚本修改 AddColumn("Tests", "LastChanged", c => c.DateTimeOffset(nullable: false, defaultValueSql: "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"));

4.使用.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)方法

打完收工

另外

如其他数据库时间戳类型映射模型时的类型不为byte[]时 都可以用此方法来解决

ef版本也不限于4.3.1 (没有测试)

请其他使用高版本ef并且使用其他数据库的TX 帮忙测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值