使用 EF Core 和 MySQL 实现行版本的更好方法?

2024-02-04

如果我在模型中使用以下字段:

[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 增量,因此只对数据库进行一次更新(我假设触发器实际上每次都会进行这两次更新)?


好吧,我想出了一个似乎不需要触发器就能很好地发挥作用的策略。

我添加了一个简单的界面:

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 字段的关键。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 EF Core 和 MySQL 实现行版本的更好方法? 的相关文章

随机推荐

  • Xcode 源自动格式化

    As a C developer I have become highly dependent on the automatic formatting in Visual Studio 2008 Specifically I will us
  • 从 mysql_connect() 获取 PHP PDO 连接?

    我有一个旧版 PHP MySQL 应用程序调用 mysql connect 大量现有的下游代码使得mysql query 使用此连接直接或通过包装器进行调用 对于我在应用程序上开发的新代码 我想开始使用 PDO 如果我使用相同的主机 用户
  • “DataLoader”对象不支持索引

    我已经通过此 pytorch api 通过设置 download True 下载了 ImageNet 数据集 但我无法迭代数据加载器 错误显示 DataLoader 对象不支持索引 trainset torch utils data Dat
  • 调用mapViewDidFailLoadingMap委托方法时出现错误== 0

    在我的视图控制器中 我创建了一个 MKMapView 对象 我将委托设置为 self 并在 ViewController 中实现 void mapViewDidFailLoadingMap MKMapView mapView withErr
  • Spring data - 根据先前的插入插入数据

    我需要将数据保存到两个表中 一个实体和一个关联表 我只是用以下命令保存我的实体save 我的实体存储库中的方法 然后 为了性能 我需要将行插入到关联表中原生sql 这些行有我之前保存的实体的引用 问题来了 我得到一个完整性约束异常关于外键
  • jQuery - 窗口焦点、模糊事件未触发 - 适用于 Firefox 和 Chrome

    简而言之 我编写了一个简单的聊天应用程序供我和我的朋友使用 当运行应用程序的窗口没有焦点 最小化或位于其他窗口后面 并且出现消息时 我想更改窗口标题栏以充当警报 就像 Google 的聊天应用程序在 GMail 中所做的那样 在 Firef
  • 如何在 Phpunit 的静态提供程序中创建测试双打?

    Phpunit 10 已弃用非静态测试提供程序 这使得在提供者内部创建测试替身成为问题 因为像这样的方法createMock or createStub 不是静态的 这是一个演示该问题的假测试 public function provide
  • 在单独的线程中执行操作以解锁 UI

    我有一个用于生成报告的表格 我们正在使用RDLC报告并且报告被加载到aspx page 所以这是代码Form 表单目标设置为 blank 并在新选项卡中打开 using Html BeginForm AssetReports AssetRe
  • 根据常识,什么是正确的: (int) blabla * 255.99999999999997 或 round(blabla*255)?

    最近我在 webkit 源代码中发现了这个有趣的事情 与颜色转换 hsl 到 rgb 相关 http osxr org android source external webkit Source WebCore platform graph
  • MongoDB 中多租户数据库的推荐方法是什么?

    我正在考虑使用 MongoDB 创建一个多租户应用程序 我还没有猜测我会有多少租户 但我希望能够扩展到数千个 我可以想到三种策略 同一集合中的所有租户 使用特定于租户的字段来确保安全 单个共享数据库中每个租户 1 个集合 每个租户 1 个数
  • 使用 python 从 LaTeX 文件中提取特定部分

    我有一组 LaTeX 文件 我想为每个提取 抽象 部分 begin abstract end abstract 我已经尝试过这里的建议 如何解析LaTex文件 https stackoverflow com questions 307523
  • 方法的多个返回类型

    我正在尝试用 Rust 编写一个简单的电视剧文件重命名器 文件名被解析 并且可能是多种类型之一 基于日期 基于季节 剧集编号等 然后 此解析后的文件将转换为包含数据库中数据的 填充文件 然后将其格式化为新文件名 最初我尝试让parse方法采
  • DB PHP 中的条目数

    我正在创建一个函数来显示现在有多少用户在线 这是基于过去 5 分钟内打开页面的人 每个页面加载都保存到我的数据库中 如下所示 目前我有以下代码 query mysql query SELECT user id timestamp FROM
  • Vuex - 绑定助手中的动态命名空间(mapState,...)

    我正在动态注册 vuex 存储模块 store registerModule home grid GridStore 然后在组件中 export default name GridComponent props namespace type
  • 哪些版本控制工具可用于 MongoDB [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我计划将基于 mongodb 的迁移工具集成到我的 spring boot 应用程序中 该应用程序在项目中具有 spring data 依赖
  • 在sqlite数据库中保存日志表?

    我正在寻找一种方法来设置 通过 SQL 一个日志表 其中包含对我的 sqlite 数据库所做的所有操作 最好是向数据库发出的插入 创建表等语句 我确信有办法通过在每个表上设置触发器来做到这一点 但这只是太多的工作 而且如果我稍后更改数据库的
  • 在 C# 中通过委托实现观察者模式?

    有一个问题已经回答了 那就是在C 中 观察者模式不是已经使用事件实现了吗 https stackoverflow com questions 32034 in c isnt the observer pattern already impl
  • Rails 验证中的单词计数

    我使用以下验证来计算 Rails 中的单词数 我从 Rails 文档中获取了示例 但它并不真正准确 validates body length gt minimum gt 50 maximum gt 300 tokenizer gt lam
  • 将日志文件保持在一定大小

    我有一个在信息亭 C WPF 中的独立平板电脑上运行的应用程序 它对文本文件执行一些典型的日志记录操作 随着这些日志的增长 PC 具有有限的磁盘空间来存储这些日志 我需要做的是能够指定日志文件允许的最大大小 如果在尝试写入日志时超出最大大小
  • 使用 EF Core 和 MySQL 实现行版本的更好方法?

    如果我在模型中使用以下字段 DatabaseGenerated DatabaseGeneratedOption Computed Timestamp public DateTime RowVersion get set 然后将该列定义为 R