C# 实体框架Code First方法 C# EF Core如何使用Code First

来源:这里教程网 时间:2026-02-21 17:40:00 作者:

Code First 不是“先写代码再生成数据库”的简单流程,而是以 C# 类(实体)为唯一数据模型源头,由 EF Core 自动推导并管理数据库结构的开发模式。它要求你放弃手动建表思维,把注意力放在领域对象设计和迁移生命周期上。

定义实体类时必须注意的三个约束

EF Core 会根据约定自动映射属性,但一旦违反默认规则,就会导致迁移失败或运行时报错

InvalidOperationException

public
属性且有
get
set
访问器才会被识别为字段;
private set
可接受,但
readonly
字段或只读属性不会映射
主键命名必须是
Id
{ClassName}Id
(如
UserId
),否则需用
[Key]
显式标记
导航属性(如
public ICollection<order> Orders { get; set; }</order>
)必须声明为
virtual
(启用延迟加载时)或使用
Include()
显式加载,否则查询时为空

DbContext 子类中如何正确配置关系

仅靠属性命名无法表达所有关系类型(如一对多、多对多、自引用)。必须重写

OnModelCreating
方法,用 Fluent API 补充约定之外的逻辑。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>()
        .HasOne(o => o.User)
        .WithMany(u => u.Orders)
        .HasForeignKey(o => o.UserId);
<pre class='brush:php;toolbar:false;'>modelBuilder.Entity<User>()
    .HasIndex(u => u.Email)
    .IsUnique();
modelBuilder.Entity<PostTag>()
    .HasKey(pt => new { pt.PostId, pt.TagId });

}

常见疏漏:

HasOne().WithMany()
忘记配对反向导航属性,或在多对多中间表中没用
HasKey
显式指定复合主键,会导致迁移生成错误的外键约束。

执行迁移时最容易出错的三步操作

迁移不是“一键生成”,而是一系列可审查、可回滚的变更脚本。跳过其中任意一步,都可能让本地数据库与代码模型脱节。

修改实体后,必须先运行
dotnet ef migrations add InitialCreate
(或带描述的名称),生成
Migrations/xxx_InitialCreate.cs
—— 这个文件不能手动改,它是 EF Core 推导出的“差量”
检查生成的
Up(MigrationBuilder migrationBuilder)
方法是否符合预期,比如字段类型是否正确(
string
默认映射为
nvarchar(max)
,常需用
HasMaxLength(50)
限制)
执行
dotnet ef database update
才真正应用变更;若想回退,用
dotnet ef database update PreviousMigrationName
,而不是删掉迁移文件

生产环境禁用
Database.EnsureCreated()

这个方法会直接删库重建,在开发阶段看似方便,但一旦误部署到测试或生产环境,后果不可逆。

替代方案只有且必须是迁移:

首次部署:运行
dotnet ef database update
应用全部待迁移
后续更新:每次发布前生成新迁移,上线时执行
update
到最新版本
若需初始化空库,可用
dotnet ef migrations script --idempotent
生成兼容性脚本,供 DBA 审核执行

真正难的不是写第一个

DbContext
,而是让团队所有人理解:迁移文件是代码的一部分,要进 Git、要 Code Review、要和实体变更保持原子性 —— 否则迟早遇到
Microsoft.Data.SqlClient.SqlException: Invalid object name 'Users'
这类运行时错误。

相关推荐