I have added DateCreated, UserCreated, DateModified and UserModified fields to each entity by creating a BaseEntity.cs class. My requirement is to generate single table which is having all the fields of base class as columns.
public class BaseEntity
{
public DateTime? DateCreated { get; set; }
public string UserCreated { get; set; }
public DateTime? DateModified { get; set; }
public string UserModified { get; set; }
}
Here is my Student class
public class Student : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
Here is my context class
public class SchoolContext: DbContext
{
public LibraContext(DbContextOptions<SchoolContext> options)
: base(options)
{ }
public DbSet<Student> Students { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//CreatedDate
modelBuilder.Entity<BaseEntity>().Property(x => x.DateCreated).HasDefaultValueSql("GETDATE()");
//Updated Date
modelBuilder.Entity<BaseEntity>().Property(x => x.DateModified).HasDefaultValueSql("GETDATE()");
}
I have run the below migration commands to create script and update database
Add-Migration -Name "InitialMigration" -Context "SchoolContext"
update-database
It has created separate tables BaseEntity and Student in the SQL Server database. My expectation is to create a single Student table with all the BaseEntity fields as columns.
How to achieve it?
I am using ASP.NET CORE2.1
According to Microsoft Documentation you can use [NotMapped] data annotation or modelBuilder.Ignore<TEntity>(); to ignore the table creation for BaseEntity as follows:
But in your case [NotMapped] would not help you because Fluent API always has higher priority than the data annotations (attributes). So you can call modelBuilder.Ignore<BaseEntity>(); after the BaseEntity configuration in the OnModelCreating but calling modelBuilder.Ignore<BaseEntity>(); will lose the BaseEntity configurations.
So as per as I am concerned the best solution would be as follows:
Write the configuration for BaseEntity as follows:
public class BaseEntityConfigurations<TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : BaseEntity
{
public virtual void Configure(EntityTypeBuilder<TEntity> builder)
{
//CreatedDate
builder.Property(x => x.DateCreated).HasDefaultValueSql("GETDATE()");
//Updated Date
builder.Property(x => x.DateModified).HasDefaultValueSql("GETDATE()");
}
}
Then write the configuration for Student as follows:
public class StudentConfigurations : BaseEntityConfigurations<Student>
{
public override void Configure(EntityTypeBuilder<Student> builder)
{
base.Configure(builder); // Must call this
// other configurations here
}
}
Then in the OnModelCreating as follows:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new StudentConfigurations());
}
Migration will generate the only Student table with BaseEntity configuration as follows:
migrationBuilder.CreateTable(
name: "Students",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
DateCreated = table.Column<DateTime>(nullable: true, defaultValueSql: "GETDATE()"),
UserCreated = table.Column<string>(nullable: true),
DateModified = table.Column<DateTime>(nullable: true, defaultValueSql: "GETDATE()"),
UserModified = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Students", x => x.Id);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With