I am studying EF Core with database first. There is no issue to get entities and DbContext after reverse-engineering. But I couldn't understand the role(or purpose) OnModelCreating Method in DbContext(database first approach). Here is code snippet.
public partial class VitiLevuContext : DbContext
{
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Invoice> Invoices { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Invoice>(entity =>
{
entity.ToTable("Invoice");
entity.Property(e => e.DueAmount)
.IsRequired();
entity.Property(e => e.PaidAmount).HasColumnType("money");
entity.HasOne(d => d.Order)
.WithMany(p => p.Invoices)
.OnDelete(DeleteBehavior.Cascade)
.HasForeignKey(d => d.OrderId)
.HasConstraintName("FK__Invoice__OrderId__44FF419A");
});
modelBuilder.Entity<Order>(entity =>
{
entity.ToTable("Order");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
Database has a relation and "NOT NULL Contraints".
- ALTER TABLE [dbo].[Invoice] ADD FOREIGN KEY ([OrderId]) REFERENCES [dbo].Order ON DELETE CASCADE.
- ALTER TABLE [dbo].[Invoice] ADD [DueAmount] int NOT NULL
The OnModelCreating method represents well. I created very simple Rest API project and tested add/delete for Order/Invoice. "NOT NULL Constraints" and "Cascade deleting" may be verified on database not EF model side. (In case of creating an invoice instance with null DueAmount, I expected exceptions before submitting to SQL)
My question is very simple. Can I delete "OnModelCreating" method if don't consider migration? (I thought the OnModelCreating method is only for migration purpose.)
CodePudding user response:
If you follow the Entity framework model naming convention and your model directly reflects your database table name, column names and so on, you don't need the OnMOdelCreating method. This is because the entity framework will generate the code behind the scene.
But, if you want customization, for example, your model field name does not match your database table column name, you configure that on the OnModelCreating method. Another way of using this configuration is called fluent API.
This doesn't mean you have to use the OnModelCreating method. There are other options for customization. Which is DataAnotation.
For example:
If you have a model named User...
public class User
{
public int Id { get; set; }
public string FullName { get; set; }
public string Password { get; set; }
}
on your DbContext, you set the following
public AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) {}
public DbSet<User> Users { get; set; }
}
So, by convention, the Entity framework expects
- A table named Users, because of the name you used on the DbSet property for the User model.
- It uses Id as the primary key.. because the model property name Id
Entity framework will set this all up for you.
When we come to the custom configuration, let's say your model property name Password is not the same as the Users table name property Pwd. You have to tell the entity framework in one of the following ways.
using the OnModelCreating method (fluent API)
protected override void OnModelCreating(ModelBuilder modelBuild) { modelBuilder.Entity<User>(entity => { entity.Property(p => p.Password) .HasColumnName("Pwd"); }) }
The other way is Data annotation
public class User { public int Id { get; set; } public string FullName { get; set; } [Column("Pwd")] public string Password { get; set; } }