如果我在我的模型中使用以下字段:[DatabaseGenerated(DatabaseGeneratedOption.Computed)][Timestamp]public DateTime RowVersion { get; set; }然后将列定义为`RowVersion` datetime NOT NULL DEFAULT CURRENT_T...

如果我在我的模型中使用以下字段:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public DateTime RowVersion { get; set; }
然后将列定义为
`RowVersion` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
我从EF获得了正确的乐观并发行为.也就是说,我对使用时间戳感到很兴奋,因为它似乎只是第二个分辨率.虽然有2个客户尝试在1秒内更新同一记录的可能性很大,但肯定会发生,不是吗?
因此,考虑到这一点,我更喜欢一个简单的整数,在每次更新时以原子方式递增1.这样就不可能错过冲突.我把我的定义改为:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public long RowVersion { get; set; }
问题是,MySQL不会自动增加它.所以我创建了一个触发器:
CREATE TRIGGER update_row_version BEFORE UPDATE on client
FOR EACH ROW
SET NEW.RowVersion = OLD.RowVersion + 1;
现在这一切都有效. EF在需要时抛出DbUpdateConcurrencyException,并且由于时间窗口而不可能错过更新.但是,它使用触发器,我继续阅读它们对性能有多糟糕.
那么还有更好的方法吗?也许某种方法来覆盖DbContext的SaveChanges()来在客户端上执行RowVersion增量,因此只对DB进行一次更新(我假设触发器实际上每次都进行两次更新)?
解决方法:
好吧,我想出了一个似乎运行良好的策略,不需要触发器.
我添加了一个简单的界面:
interface ISavingChanges
{
void OnSavingChanges();
}
该模型现在看起来像这样:
public class Client : ISavingChanges
{
// other fields omitted for clarity...
[ConcurrencyCheck]
public long RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
}
然后我像这样覆盖了SaveChanges:
public override int SaveChanges()
{
foreach (var entity in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified))
{
var saveEntity = entity.Entity as ISavingChanges;
saveEntity.OnSavingChanges();
}
return base.SaveChanges();
}
这一切都按预期工作. ConcurrencyCheck属性是使EF在UPDATE SQL的SET和WHERE子句中包含RowVersion字段的关键.
本文标题为:c# – 使用EF Core和MySQL实现行版本的更好方法?


基础教程推荐
- C#实现Excel转PDF时设置内容适应页面宽度 2023-05-26
- c# – 如何判断linq to sql对象是新的,修改的还是未更改的? 2023-11-10
- 浅谈C#9.0新特性之参数非空检查简化 2023-02-25
- C#通过HttpWebRequest发送带有JSON Body的POST请求实现 2023-04-27
- c# – 简单注入器 – Windows窗体示例已损坏 2023-09-18
- centos7部署.net core2.1 2023-09-28
- WPF实现3D粒子波浪效果 2023-03-09
- c# – “使用SqlDataReader时无效尝试在读取器关闭时调用Read” 2023-11-10
- C#中的GDI+图像编程详解 2023-06-08
- C# 获取硬盘号,CPU信息,加密解密技术的步骤 2023-03-28