实体框架6 mysql rowversion

时间:2015-08-20 08:17:03

标签: c# mysql entity-framework ef-code-first entity-framework-6

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

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

3 个答案:

答案 0 :(得分:4)

首先,如果您使用自动迁移,我认为属性属性不足以创建正确的字段类型。
这里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; }

答案 1 :(得分:0)

遗憾的是,如果使用DateTime值进行乐观锁定,则可能会因Oracle MySQL驱动程序中的精度损失而失败。有bug reports这个已经存在多年了,显然他们拒绝修复。

更新:我刚刚提交了PR to MySQL .NET Connector v6.9.10,为此问题提供了解决方案,可在EF和非EF应用程序之间提供乐观锁定。有关详细信息,请参阅https://stackoverflow.com/a/50147396/365261

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

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

顺序rowversion

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

随机rowversion

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; }

答案 2 :(得分:0)

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

对于 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),它也会存储毫秒,从而帮助解决上述精度问题。