Understanding the ValueGeneratedOnAdd feature

See original GitHub issue

Steps to reproduce

I am trying to build an example of .ValueGeneratedOnAdd() and .ValueGeneratedOnAddOrUpdate() for a book. The .ValueGeneratedOnAddOrUpdate() property doesn’t seem to be updated.

The issue

Summary: I have a CreatedOn property with the .ValueGeneratedOnAdd() setting and UpdatedOn property with the .ValueGeneratedOnAddOrUpdate() setting. If I create an entry, wait a second, and update that entry the UpdatedOn is not updated. I also notice the SQL database column UpdatedOn isn’t changing.

I assume I have the setup wrong, but I don’t see where. You input would be appreciated.

My DbContext is:

public class EfCoreContext : DbContext             
{
    public DbSet<BookAndAuthor> 
        BookAndAuthors { get; set; }               

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

    protected override void 
        OnModelCreating(ModelBuilder modelBuilder) 
    {
        modelBuilder.Entity<BookAndAuthor>()
            .Property(x => x.CreatedOn)
            .HasDefaultValueSql("getutcdate()")
            .ValueGeneratedOnAdd();

        modelBuilder.Entity<BookAndAuthor>()
            .Property(x => x.UpdatedOn)
            .HasDefaultValueSql("getutcdate()")
            .ValueGeneratedOnAddOrUpdate();

        ...//setting for other properties left out
        base.OnModelCreating(modelBuilder);
    }
}

My class is:

public class BookAndAuthor
{
    public int BookAndAuthorId { get; set; }  
    public DateTime CreatedOn { get; set; }
    public DateTime UpdatedOn { get; set; }
   ... //other properties removed     
}

My Unit Test is:

[Fact]
public void TestDefaultValueAddOrUpdateOk()
{
    //SETUP
    var connection = this.GetUniqueDatabaseConnectionString();
    var optionsBuilder =
        new DbContextOptionsBuilder<EfCoreContext>();

    optionsBuilder.UseSqlServer(connection);
    var options = optionsBuilder.Options;

    using (var db = new EfCoreContext(options))
    {
        db.Database.EnsureCreated();
        var books = EfTestData.CreateFourBooks();
        db.BookAndAuthors.AddRange(books);
        db.SaveChanges();
        Thread.Sleep(1000);

        //ATTEMPT 
        var firstBook = books.First();
        firstBook.Description = $"has changed on {DateTime.UtcNow:u}";
        db.SaveChanges();

        //VERIFY                                    
        firstBook.UpdatedOn.ShouldNotEqual(firstBook.CreatedOn);
    }
}

The test fails, as the UpdatedOn is the same as the CreatedOn value. Looking at the time in the description the UpdatedOn value has not been updated.

If you are seeing an exception, include the full exceptions details (message and stack trace). n/a

Further technical details

EF Core version: “Microsoft.EntityFrameworkCore.SqlServer”: “1.1.0-preview1-final”, Operating system: Windows 10 Visual Studio version: Microsoft Visual Studio Professional 2015 Version 14.0.25425.01 Update 3 Microsoft .NET Framework Version 4.6.01586

Other details about my project setup: Pretty normal setup.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
ajcvickerscommented, Nov 10, 2016

@JonPSmith You need to use HasComputedColumnSql rather than HasDefaultValueSql. Also, you don’t actually need the calls to ValuGeneratedOnAdd or ValueGeneratedOnAddOrUpdate because when you call HasDefaultValueSql it automatically sets ValuGeneratedOnAdd and when you call HasComputedColumnSql it automatically sets ValueGeneratedOnAddOrUpdate. So your code should be:

modelBuilder.Entity<BookAndAuthor>()
    .Property(x => x.CreatedOn)
    .HasDefaultValueSql("getutcdate()");

modelBuilder.Entity<BookAndAuthor>()
    .Property(x => x.UpdatedOn)
    .HasComputedColumnSql("getutcdate()");

0reactions
ajcvickerscommented, Apr 24, 2017

@trinvh Can you please open a new issue for this including a full code listing or project that reproduces the problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Generated Values - EF Core
Database columns can have their values generated in various ways: primary key columns are frequently auto-incrementing integers, other columns ...
Read more >
PropertyBuilder.ValueGeneratedOnAdd Method
Configures a property to have a value generated only when saving a new entity, unless a non-null, non-temporary value has been set, in...
Read more >
c# - ValueGeneratedOnAdd has no effect
When I retrieve data I get entities with filled Id properties (1, 2, 3 etc) but I think It doesn't matter. Actually it...
Read more >
DatabaseGenerated Attribute in EF 7 & EF Core
Use the ValueGeneratedOnAdd() method of Fluent API to specify an Identity property in EF Core, as shown below. modelBuilder.Entity<Course>() .
Read more >
Value Generation | Npgsql Documentation
In other words, when ValueGeneratedOnAdd is specified on a short , int or long property, the Npgsql provider will automatically map it to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found