Entity Framework Core Configuration Reference

Convention-Based Configuration

Core Mapping Rules

  1. Table names correspond to the DbSet property names defined in your DbContext
  2. Column names derive from entity property names, with data types selected based on the most compatible match for the property type (customizable)
  3. Column nullability aligns with the underlying property's nullability setting
  4. Properties named Id automatically become primary keys
    • Integer-based keys (short, int, long) utilize auto-increment behavior by default
    • Guid primary keys leverage the Guid generation mechanism

Configuration Approaches

Combined Usage

Both methods share overlapping functionality and can be used together, though this approach is generally discouraged.

Data Annotations

Attributes applied directly to entity classes provide a straightforward but tightly coupled configuration method.

[Table("T_Books")]
public class Book
{
    public long Id { get; set; }
    [Required]
    [MaxLength(50)]
    public string Title { get; set; }
    public DateTime PubTime { get; set; }
    public double Price { get; set; }
    [Required]
    [MaxLength(50)]
    public string AuthorName { get; set; }
}

Fluent API with Separate Configuration Classes

Extracting configuration into dedicated classes promotes separation of concerns and improves maintainability. This is the recommended approach.

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
        builder.Property(b => b.Title).HasMaxLength(50).IsRequired();
        builder.Property(b => b.AuthorName).HasMaxLength(20).IsRequired();
    }
}

public class LibraryDbContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlServer("Server=.;Database=demo1;Trusted_Connection=True;MultipleActiveResultSets=true");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    }
}

Fluent API Reference

Table Views

Map entities to database views. This approach is not recommended for most scenarios.

modelBuilder.Entity<Blog>().ToView("blogsView");

Excluding Properties from Mapping

Prevent specific properties from being persisted to the database.

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
        builder.Ignore(b => b.Price);
    }
}

Customizing Column Names

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
        builder.Property(b => b.PubTime).HasColumnName("pub_time");
    }
}

modelBuilder.Entity<Book>().Property(b => b.Title).HasColumnName("book_title");

Specifying Column Data Types

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
        builder.Property(b => b.Title).HasColumnType("varchar(200)");
    }
}

Primary Key Configuration

By default, properties named Id or EntityNameId serve as primary keys. Use HasKey() to override this behavior. Composite keys are supported but discouraged.

public class BookConfiguration : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
        builder.HasKey(b => b.Id);
    }
}

public class LibraryDbContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // ...
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Book>().HasKey(x => x.Id);
    }
}

Configuring Value Generation

For computed columns and similar scenarios. This feature is generally not recommended.

builder.Property(b => b.Price).ValueGeneratedOnAdd();

Setting Default Values

builder.Property(b => b.Title).HasDefaultValue("Untitled");

modelBuilder.Entity<Book>().Property(b => b.Title).HasDefaultValue("Untitled");

Index Configuration

Standard Index

builder.HasIndex(b => b.Title);

modelBuilder.Entity<Book>().HasIndex(b => b.Title);

Composite Index

builder.HasIndex(b => new { b.Id, b.Title });

modelBuilder.Entity<Book>().HasIndex(b => new { b.Id, b.Title });

Unique Index

builder.HasIndex(b => b.Title).IsUnique();

modelBuilder.Entity<Book>().HasIndex(b => b.Title).IsUnique();

Clustered Index

builder.HasIndex(b => b.Title).IsClustered();

modelBuilder.Entity<Book>().HasIndex(b => b.Title).IsClustered();

Method Chaining Considerations

Chained method calls require that each preceding method returns an object capable of invoking the next method in the chain.

Tags: entity-framework-core ef-core ORM fluent-api data-annotations

Posted on Sun, 10 May 2026 05:48:38 +0000 by Jen_u41