简体   繁体   English

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

[英]Better way to implement a row version with EF Core and MySQL?

If I use the following field in my model: 如果我在我的模型中使用以下字段:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public DateTime RowVersion { get; set; }

and then define the column as 然后将列定义为

`RowVersion` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

I get the proper optimistic concurrency behavior from EF. 我从EF获得了正确的乐观并发行为。 That said, I'm not thrilled about using a timestamp for this since it appears to only be second resolution. 也就是说,我对使用时间戳感到很兴奋,因为它似乎只是第二个分辨率。 And while there isn't a big chance of having 2 clients try to update the same record within 1 second, it certainly could happen, no? 虽然有2个客户尝试在1秒内更新同一记录的可能性很大,但肯定会发生,不是吗?

So with that in mind I would prefer a simple integer that atomically increments by 1 on every update. 因此,考虑到这一点,我更喜欢一个简单的整数,在每次更新时以原子方式递增1。 This way there is no possibility of missing a conflict. 这样就不可能错过冲突。 I changed my definition to: 我把我的定义改为:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public long RowVersion { get; set; }

The problem is, MySQL won't automatically increment this. 问题是,MySQL不会自动增加它。 So I created a trigger: 所以我创建了一个触发器:

CREATE TRIGGER update_row_version BEFORE UPDATE on client 
FOR EACH ROW
SET NEW.RowVersion = OLD.RowVersion + 1;

And now this all works. 现在这一切都有效。 EF throws the DbUpdateConcurrencyException when needed and there's no chance of missing an update due to a timing window. EF在需要时抛出DbUpdateConcurrencyException,并且由于时间窗口而不可能错过更新。 But, it uses a trigger and I keep reading about how bad they are for performance. 但是,它使用触发器,我继续阅读它们对性能有多糟糕。

So is there a better way? 那么还有更好的方法吗? Perhaps some way to override DbContext's SaveChanges() to perform the RowVersion increment on the client and therefore only have a single update on the DB (I'm assuming the trigger actually makes this two updates each time)? 也许某种方式来覆盖DbContext的SaveChanges()来在客户端上执行RowVersion增量,因此只对DB进行一次更新(我假设触发器实际上每次都进行两次更新)?

Ok, I figured out a strategy that seems to work well with no trigger needed. 好吧,我想出了一个似乎运行良好的策略,不需要触发器。

I added a simple interface: 我添加了一个简单的界面:

interface ISavingChanges
{
    void OnSavingChanges();
}

The model looks like this now: 该模型现在看起来像这样:

public class Client : ISavingChanges
{
    // other fields omitted for clarity...


    [ConcurrencyCheck]
    public long RowVersion { get; set; }

    public void OnSavingChanges()
    {
        RowVersion++;
    }
}

And then I overrode SaveChanges like this: 然后我像这样覆盖了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();
    }

This is all working as expected. 这一切都按预期工作。 The ConcurrencyCheck attribute was the key to getting EF to include the RowVersion field in both the SET and WHERE clauses of the UPDATE SQL. ConcurrencyCheck属性是使EF在UPDATE SQL的SET和WHERE子句中包含RowVersion字段的关键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有更好的方法可以在EF中实现OnModelCreating方法? - Is there a better way to implement OnModelCreating method in EF? 在 EF Core 中更新数据的更好方法是什么 - What is better way to update data in EF Core 检查 ID 列表是否有效的更好方法(EF Core) - Better way to check if a list of IDs is valid (EF Core) Linux上的Dotnet核心1.1:在使用EF Core播种数据时,有什么特别的方式比其他方式更好? - Dotnet core 1.1 on linux: Any particular way thats better than others when seeding data with EF Core? 在 ASP.NET Core 中使用 EF Core 加载单个实体及其相关数据的更好方法是什么? - Which is the better way to load a single entity with its related data with EF Core in ASP.NET Core? 有没有更好的方法来实现多线程? - Is there a better way to implement multithreading? 有没有更好的方法来实现依赖关系? - Is there a better way to implement dependencies? 实施行为的更好方法 - Better way to implement a behavior EF Core Mysql性能 - EF Core Mysql performance 是否有更好的方法在 EF Core 中包含其他字段/列而不加载整个导航属性 - Is there a better way to include additional fields/columns in EF Core without loading the whole navigation property
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM