实体框架6 mysql rowversion

Posted

技术标签:

【中文标题】实体框架6 mysql rowversion【英文标题】:entity framework 6 mysql rowversion 【发布时间】:2015-11-13 18:53:45 【问题描述】:

我在我的 sql 中使用实体框架 6,并且似乎 mysql 不支持行版本字节数组。 任何帮助如何实现这一点。

[Column(TypeName = "timestamp")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime TimeStamp  get; set; 

【问题讨论】:

我正在使用 here 描述的解决方案,到目前为止没有问题。一切正常。 【参考方案1】:

如果您遇到此问题,我通过以下操作解决了它:

对于 MYSQL,您必须使用 DateTime,因为 byte[] 不起作用

public DateTime RowVersion  get; set; 

然后在您的上下文类中,转到 OnModelCreating

protected override void OnModelCreating(ModelBuilder builder)

      builder.Entity<YourClass>()
           .Property(c => c.RowVersion)
           .HasColumnType("datetime(3)")
           .IsRequired()
           .IsRowVersion();

通过将列类型设置为 datetime(3),它也将存储毫秒,从而有助于解决上述精度问题。

【讨论】:

【参考方案2】:

遗憾的是,如果您使用 DateTime 值进行乐观锁定,它可能会由于 Oracle MySQL 驱动程序中的精度损失而失败。上面有bug reports,它们已有多年历史,显然他们拒绝修复。

更新:我刚刚提交了一个PR to MySQL .NET Connector v6.9.10,它为这个问题提供了一个解决方案,在 EF 和非 EF 应用程序之间提供了乐观锁定。详情请见https://***.com/a/50147396/365261。

作为一种解决方法,您可以创建自己的 Non-DATETIME 乐观锁定列。 通过 DB 触发器(而不是在 c# 代码中)设置此值,我们确保它适用于外部应用程序和任何 DB 管理任务。

添加栏目rowversion BIGINT NOT NULL DEFAULT 0, 添加触发器以将此字段设置为随机值或顺序值。 在新列上添加 E6 属性。

顺序行版本

CREATE TRIGGER `trg_mytable_before_update` 
BEFORE UPDATE ON `mytable` 
FOR EACH ROW SET NEW.`rowversion` = OLD.`rowversion` + 1;

随机行版本

CREATE TRIGGER `trg_mytable_before_update` 
BEFORE UPDATE ON `mytable` 
FOR EACH ROW SET NEW.`rowversion` = FLOOR(1 + RAND() * POW(2,54));

EF6 属性

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[ConcurrencyCheck]
[Column("rowversion", TypeName = "bigint")]
public virtual long RowVersion  get; set; 

【讨论】:

【参考方案3】:

首先,如果您使用自动迁移,我认为属性属性不足以创建正确的字段类型。https://dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html 这里有 EF 提供程序应该生成的语法来创建自动生成/更新的时间戳

创建正确的字段类型后,您可以尝试 2 次:

-将字段标记为时间戳

[Timestamp]
public DateTime TimeStamp  get; set; 

我认为 EF 不需要 Timestamp 字段是 byte[]。时间戳应该只表示这是数据库生成的字段,并且乐观并发使用该字段(即更新查询包含要更新的记录键和该字段的位置)。但通常 EF 并不像我想的那样工作......

-将该字段标记为由数据库生成,并作为用于检查乐观并发异常的字段

[ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime TimeStamp  get; set; 

【讨论】:

以上是关于实体框架6 mysql rowversion的主要内容,如果未能解决你的问题,请参考以下文章

无法为实体框架6使用MySQL连接

使用 MSSQL 和 MySQL 数据库作为实体框架 6 模型

表 'DBNAME.dbo.TableNAME' 不存在 MySQL 的实体框架 6

带有 Mysql 和 NullReferenceException 的实体框架 6

使用 MySQL 和实体框架 6 StrongTypingException 错误

使用实体框架6将数据从数据库存储到本地