Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change token [Timestamp] has no effect for SQLite #22193

Closed
akovac35 opened this issue Aug 24, 2020 · 1 comment
Closed

Change token [Timestamp] has no effect for SQLite #22193

akovac35 opened this issue Aug 24, 2020 · 1 comment

Comments

@akovac35
Copy link

akovac35 commented Aug 24, 2020

I have a table with the following column:

[Timestamp]
public byte[]? OpCounter { get; set; }

When inserting a new row in the table, the object instance is not automatically updated - OpCounter value is null after save. Also, if I later query the data, the OpCounter value is still null. Similarly for updates.

To Reproduce

Simply run the GitHub code and review the failing test. Each test has Additional output containing EFCore logs etc. The working test suggests a solution - introduce triggers during EnsureCreated and in Migrations, similarly as per suggested solution.

Suggested solution

Create, update or delete triggers as needed during EnsureCreated and in Migrations:

Change-token-Timestamp-has-no-effect-for-SQLite

protected void InitializeTriggers(TestSqliteContext context)
{
	var tables = context.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.GetTableName();

		foreach (var field in props)
		{
			string[] SQLs = new string[] {
	$@"CREATE TRIGGER IF NOT EXISTS Set{tableName}_{field.Name}OnUpdate
	AFTER UPDATE ON [{tableName}] FOR EACH ROW
	BEGIN
		UPDATE [{tableName}]
		SET [{field.Name}] = randomblob(8)
		WHERE rowid = NEW.rowid;
	END
	",
	$@"CREATE TRIGGER IF NOT EXISTS Set{tableName}_{field.Name}OnInsert
	AFTER INSERT ON [{tableName}] FOR EACH ROW
	BEGIN
		UPDATE [{tableName}]
		SET [{field.Name}] = randomblob(8)
		WHERE rowid = NEW.rowid;
	END
	"
};

			foreach (var sql in SQLs)
			{
				using (var command = context.Database.GetDbConnection().CreateCommand())
				{
					command.CommandText = sql;
					command.ExecuteNonQuery();
				}
			}
		}
	}
}

Additional context

Microsoft.Data.Sqlite version:
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.7" />
Target framework:
<TargetFramework>netcoreapp3.1</TargetFramework>
Operating system:
Windows 10

@ajcvickers
Copy link
Contributor

Duplicate of #2195

@ajcvickers ajcvickers marked this as a duplicate of #2195 Aug 24, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants