Pomelo.entityframeworkcore.mysql: Useless AlterColumn operations are generated for TimeStampAttribute-marked properties on every migration

Created on 20 Jun 2019  路  10Comments  路  Source: PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

Steps to reproduce

Consider the following model:

public class TestContext : DbContext
{
   public DbSet<TestEntity> TestEntities { get; set; }
}

public class TestEntity
{
   [Key]
   public int Id { get; set; }

   public string Name { get; set; }

   [Required, TimeStamp, ConcurrencyCheck]
   public byte[] RowVersion { get; set; }
}

The issue

When I make a migration, useless AlterColumn operations are issued, even if there are no changes in the model.

public partial class TestMigration : Migration
{
   protected override void Up(MigrationBuilder migrationBuilder)
   {
      migrationBuilder.AlterColumn<DateTime>(
         name: "RowVersion",
         table: "TestEntities",
         rowVersion: true,
         nullable: false,
         oldClrType: typeof(DateTime))
         .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn);
   }

   protected override void Down(MigrationBuilder migrationBuilder)
   {
      migrationBuilder.AlterColumn<DateTime>(
         name: "RowVersion",
         table: "TestEntities",
         nullable: false,
         oldClrType: typeof(DateTime),
         oldRowVersion: true)
         .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn);
   }
}

Further technical details

MySQL version: 8.0
Operating system: Windows 10 Pro
Pomelo.EntityFrameworkCore.MySql version: 2.2.0

type-bug

Most helpful comment

This specific problem is fixed by #896 [...]

The intonation here is on specific. The issue @msvprogs posted was about a byte[] property with the [Required, TimeStamp] attributes, which should be fixed.

While fixing the issue, others came up and we opened an issue on the EF Core repo upstream, that also contained a sub issue about the same property setup described here, but without the [Required] attribute. It would look like this:

```c#
[Timestamp] // <-- without [Required] attribute
public byte[] RowVersion { get; set; }


This one has not been fixed yet, because it is blocked by another EF Core issue:

> On a second look we can't yet mark them as non-nullable before https://github.com/aspnet/EntityFrameworkCore/issues/13850 is fixed as we can still send `nulls`.

You can read up on this one here: https://github.com/aspnet/EntityFrameworkCore/issues/18592

---

If you think your issue is not related to the one described above, than please post your model class, its definition and the generated migrations.

If your issue is related and you need a workaround, the following line should work:

```c#
[Timestamp, Required] // <-- use [Required] attribute
public byte[] RowVersion { get; set; }

All 10 comments

I have the same issue - I can generate the migration and apply it, but all other migrations I generate have this..

A simple workaround is to use System.DateTime instead of System.Byte[] because RowVersion/Timestamp fields in MySQL use the timestamp or timestamp(6) database data type, which is mapped to the CLR data type System.DateTime:

C# [Required, TimeStamp, ConcurrencyCheck] public DateTime RowVersion { get; set; } // <-- changed from byte[] to DateTime

The support for byte[] timestamps is implemented internally by applying value converters to convert between byte[] and DateTime and seems to be a bit buggy, but should be fixable.

@caleblloyd Do you remember what the reason for removing RelationalTypeMapping _rowversion from MySqlTypeMappingSource (and therefore the official mapping between System.DateTime and a RowVersion) was?

Yes, it worked, thanks :)

This might be an EF Core bug.
I opened an issue on their repo.

Okay, that might be so. ValueConverters handling is still far from perfect (

This specific problem is fixed by #896 and https://github.com/aspnet/EntityFrameworkCore/pull/18599.
There is another issues that came up while fixing this one, that is blocked by https://github.com/aspnet/EntityFrameworkCore/issues/13850.

I am running v3.1.0-rc1.final and am still having this issue. I even changed all my byte[] columns to DateTime and still have the issue. Am I missing something here?

This specific problem is fixed by #896 [...]

The intonation here is on specific. The issue @msvprogs posted was about a byte[] property with the [Required, TimeStamp] attributes, which should be fixed.

While fixing the issue, others came up and we opened an issue on the EF Core repo upstream, that also contained a sub issue about the same property setup described here, but without the [Required] attribute. It would look like this:

```c#
[Timestamp] // <-- without [Required] attribute
public byte[] RowVersion { get; set; }


This one has not been fixed yet, because it is blocked by another EF Core issue:

> On a second look we can't yet mark them as non-nullable before https://github.com/aspnet/EntityFrameworkCore/issues/13850 is fixed as we can still send `nulls`.

You can read up on this one here: https://github.com/aspnet/EntityFrameworkCore/issues/18592

---

If you think your issue is not related to the one described above, than please post your model class, its definition and the generated migrations.

If your issue is related and you need a workaround, the following line should work:

```c#
[Timestamp, Required] // <-- use [Required] attribute
public byte[] RowVersion { get; set; }

Perfect many thanks for the detailed explanation. Your workaround worked perfectly.

@msvprogs Thanks for creating this issue. I had this issue for almost 2 years and now it's solved. Many thanks guys. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aramirezh-dev picture aramirezh-dev  路  3Comments

a641545621 picture a641545621  路  3Comments

lauxjpn picture lauxjpn  路  3Comments

IonRobu picture IonRobu  路  3Comments

ptsneves picture ptsneves  路  3Comments