2

I have many classes looks like following:

public class ModelOneConfiguration
{
    public ModelOneConfiguration(EntityTypeBuilder<ModelOne> entity)
    {
        entity.Property(e => e.Id).IsRequired().HasDefaultValueSql("NEWID()");
        entity.Property(e => e.CreatedAt).HasDefaultValueSql("getutcdate()").ValueGeneratedOnAdd();
        entity.Property(e => e.UpdatedAt).HasDefaultValueSql("getutcdate()").ValueGeneratedOnUpdate();
        entity.Property(e => e.FirstName).IsRequired();
        entity.Property(e => e.LastName).IsRequired();         
        entity.Property(e => e.Email).IsRequired();
    }

}

And call it from Db context class:

protected override void OnModelCreating(ModelBuilder builder)
{
    new ModelOneConfiguration(builder.Entity<ModelOne>());
    ….other classes as well…
    base.OnModelCreating(builder);       
}

When I migrate it works fine with following results:

Id = table.Column<Guid>(nullable: false, defaultValueSql: "NEWID()"),
CreatedAt = table.Column<DateTimeOffset>(nullable: false, defaultValueSql: "getutcdate()"),
UpdatedAt = table.Column<DateTimeOffset>(nullable: true, defaultValueSql: "getutcdate()"),
FirstName = table.Column<string>(nullable: false),
LastName = table.Column<string>(nullable: false),
Email = table.Column<string>(nullable: false)

So far so Good.

Now I tried to wrap up Id, CreatedAt and UpdatedAt in base class so I can use it with all my other model configuration classes. So what I did, I was following this example answered by Ivan Stoev.

So for my base class I did following

public class BaseConfiguration<TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : BaseEntities
{
    public virtual void Configure(EntityTypeBuilder<TEntity> entity)
    {
        entity.Property(e => e.Id).IsRequired().HasDefaultValueSql("NEWID()");
        entity.Property(e => e.CreatedAt).HasDefaultValueSql("getutcdate()").ValueGeneratedOnAdd();
        entity.Property(e => e.UpdatedAt).HasDefaultValueSql("getutcdate()").ValueGeneratedOnUpdate();
    }
}

Then I extended my model configure class:

public class ModelOneConfiguration : BaseConfiguration<ModelOne>
{
    public ModelOneConfiguration(EntityTypeBuilder<ModelOne> entity)
    {
        entity.Property(e => e.FirstName).IsRequired();
        entity.Property(e => e.LastName).IsRequired();
        entity.Property(e => e.Email).IsRequired();
    }
}

Now when I run migration It generate following

Id = table.Column<Guid>(nullable: false),
CreatedAt = table.Column<DateTimeOffset>(nullable: false),
UpdatedAt = table.Column<DateTimeOffset>(nullable: true),
FirstName = table.Column<string>(nullable: false),
LastName = table.Column<string>(nullable: false),
Email = table.Column<string>(nullable: false)

As we can see, defaultValueSql: "NEWID()", defaultValueSql: "getutcdate()" are just missing in Id, CreatedAt and UpdatedAt.

And I am using Core 2.2 with EF core 2.2.

My Question is very simple:

What I am doing wrong and how can this be fixed?

Peter Jacobsen
  • 618
  • 2
  • 6
  • 18
  • Is the `BaseConfiguration.Configure` method being called? – DavidG Feb 13 '19 at 13:54
  • Is there a reason the configuration in the `ModelOneConfiguration` class is done in the constructor instead of overriding the `Configure` method? – DavidG Feb 13 '19 at 13:58
  • no it is just because I have taken over an old code and was working on clean it up a bit so any suggestion are welcoming – Peter Jacobsen Feb 13 '19 at 13:59
  • In my experience, that is how it should be done, and perhaps why your code doesn't work. Move that code into the `Configure` method, and don't forget to call `base.Configure` – DavidG Feb 13 '19 at 14:00
  • By the way Iwhile you asked in your first comment, It is not true I found out that the method was not called what i did I added base.Configure(entity); and it worked, you are welcome to leave answer and any other suggestion I will accpeted it – Peter Jacobsen Feb 13 '19 at 14:00

1 Answers1

3

Your derived class should be doing the work inside the Configure method, and not in the constructor. Add an override for that, and make sure to call the base Configure method:

public class ModelOneConfiguration : BaseConfiguration<ModelOne>
{
    public override void Configure(EntityTypeBuilder<ModelOne> builder)
    {
        base.Configure(builder);

        entity.Property(e => e.FirstName).IsRequired();
        entity.Property(e => e.LastName).IsRequired();
        entity.Property(e => e.Email).IsRequired();
    }
}
DavidG
  • 113,891
  • 12
  • 217
  • 223