问题
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
回答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);
});
回答2:
The TPC pattern is currently on the backlog, which means that it is being considered for inclusion as a feature, but no date has been set as yet.
read more.
回答3:
I have resolved the issue by simple change! We have to use Student entity in modelbuilder. I was mistakenly used BaseEntity
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().Property(x => x.Created).HasDefaultValueSql("GETDATE()");
modelBuilder.Entity<Student>().Property(x => x.Updated).HasDefaultValueSql("GETDATE()");
}
Open Issue: The order of generated table columns can not be controlled by order number. This is not currently supported by .net core.
来源:https://stackoverflow.com/questions/54049471/configuring-abstract-base-class-without-creating-table-in-ef-core