Updating entity in EF Core application with SQLite gives DbUpdateConcurrencyException

后端 未结 4 793
情歌与酒
情歌与酒 2021-02-09 08:42

I try to use optimistic concurrency check in EF Core with SQLite. The simplest positive scenario (even without concurrency itself) gives me Microsoft.EntityFrameworkCore.

4条回答
  •  闹比i
    闹比i (楼主)
    2021-02-09 09:34

    Inspired by this thread on GitHub and the Ivan's answer I wrote this code to ensure on my unit testing to mimic the SQL Server concurrency.

    var connection = new SqliteConnection("DataSource=:memory:");
    
    var options = new DbContextOptionsBuilder()
                   .UseSqlite(connection)
                   .Options;
    
    var ctx = new ActiveContext(options);
    
    if (connection.State != System.Data.ConnectionState.Open)
    {
        connection.Open();
    
        ctx.Database.EnsureCreated();
    
        var tables = ctx.Model.GetEntityTypes();
    
        foreach (var table in tables)
        {
            var props = table.GetProperties()
                            .Where(p => p.ClrType == typeof(byte[])
                            && p.ValueGenerated == Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAddOrUpdate
                            && p.IsConcurrencyToken);
    
            var tableName = table.Relational().TableName;
    
            foreach (var field in props)
            {
                string[] SQLs = new string[] {
                    $@"CREATE TRIGGER Set{tableName}_{field.Name}OnUpdate
                    AFTER UPDATE ON {tableName}
                    BEGIN
                        UPDATE {tableName}
                        SET RowVersion = randomblob(8)
                        WHERE rowid = NEW.rowid;
                    END
                    ",
                    $@"CREATE TRIGGER Set{tableName}_{field.Name}OnInsert
                    AFTER INSERT ON {tableName}
                    BEGIN
                        UPDATE {tableName}
                        SET RowVersion = randomblob(8)
                        WHERE rowid = NEW.rowid;
                    END
                    "
                };
    
                foreach (var sql in SQLs)
                {
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.ExecuteNonQuery();
                    }
                }
            }
        }
    }
    

提交回复
热议问题