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

Issue with scaffolding a column with DATETIME NULL ON UPDATE CURRENT_TIMESTAMP #958

Closed
baronics opened this issue Nov 21, 2019 · 5 comments · Fixed by #959
Closed

Issue with scaffolding a column with DATETIME NULL ON UPDATE CURRENT_TIMESTAMP #958

baronics opened this issue Nov 21, 2019 · 5 comments · Fixed by #959
Assignees
Milestone

Comments

@baronics
Copy link

The code

MySQL database schema:

CREATE TABLE IF NOT EXISTS `modTest`(
  `id` INT NOT NULL AUTO_INCREMENT,
  `modify_date1` DATETIME NULL,
  `modify_date2` DATETIME NOT NULL,
  `modify_date3` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modify_date4` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Scaffold generated code:

public partial class CpContext : DbContext
    {
        public CpContext()
        {
        }

        public CpContext(DbContextOptions<CpContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Modtest> Modtest { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseMySql(ConnectString);
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Modtest>(entity =>
            {
                entity.ToTable("modtest");

                entity.Property(e => e.Id)
                    .HasColumnName("id")
                    .HasColumnType("int(11)");

                entity.Property(e => e.ModifyDate1)
                    .HasColumnName("modify_date1")
                    .HasColumnType("datetime");

                entity.Property(e => e.ModifyDate2)
                    .HasColumnName("modify_date2")
                    .HasColumnType("datetime");

                entity.Property(e => e.ModifyDate3)
                    .HasColumnName("modify_date3")
                    .HasColumnType("datetime")
                    .HasDefaultValueSql("'CURRENT_TIMESTAMP'");

                entity.Property(e => e.ModifyDate4)
                    .HasColumnName("modify_date4")
                    .HasColumnType("datetime")
                    .();
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }

The issue

The modify_date4 ON UPDATE column is generating invalid code.
The entity.Property ends with .(); which must be removed in order to compile.

Further technical details

MySQL version: 8.0.17
Operating system: Windows 10
Pomelo.EntityFrameworkCore.MySql version: 3.0.0
.NET Core 3.0.100

@baronics
Copy link
Author

If I change

`modify_date4` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,

to

`modify_date4` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

then it generates:

entity.Property(e => e.ModifyDate4)
                    .HasColumnName("modify_date4")
                    .HasColumnType("datetime")
                    .HasDefaultValueSql("'CURRENT_TIMESTAMP'")
                    .ValueGeneratedOnAddOrUpdate();

@lauxjpn
Copy link
Collaborator

lauxjpn commented Nov 21, 2019

We fixed this in 3.0.0 for timestamp columns, but not for datetime columns (that do support CURRENT_TIMESTAMP since MySQL version 5.6.6.

Same goes for this line:

.HasDefaultValueSql("'CURRENT_TIMESTAMP'")

It should not contain single quotes:

.HasDefaultValueSql("CURRENT_TIMESTAMP")

The empty call is actually an EF Core issue that already got fixed for 3.1.0 (see dotnet/efcore#18579). We work around it for timestamp columns in 3.0.0 but should do the same for datetime columns.

@lauxjpn lauxjpn self-assigned this Nov 21, 2019
@lauxjpn lauxjpn added this to the 3.1.0 milestone Nov 21, 2019
@baronics
Copy link
Author

I moved to EntityFrameworkCore version 3.1.0-preview3.19554.8 and also changed my column data type from DATETIME to TIMESTAMP.
Now with:

`modify_date` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP

I get:

entity.Property(e => e.ModifyDate)
                    .HasColumnName("modify_date")
                    .HasColumnType("timestamp")
                    .ValueGeneratedOnUpdate();

The other columns with a default TIMESTAMP value have the single quotes removed.

I plan to move to the full release version of EntityFrameworkCore before my product ships next year and hopefully the Pomelo 3.1.0 will be available then too.

@lauxjpn
Copy link
Collaborator

lauxjpn commented Nov 21, 2019

Is the current 3.0.0 version of Pomelo working with the 3.1.0 preview of EF Core?
We plan to release an official 3.1.0 version until around mid-January 2020.

@baronics
Copy link
Author

I haven't run into any issues with them together yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants