EF Core 中设置索引主要通过
HasIndex方法在 Fluent API 中配置,它支持单列、多列、唯一、过滤(SQL Server)、包含列(SQL Server)等多种索引类型。关键点是:索引定义写在
OnModelCreating里,迁移生成后才真正创建到数据库。
基础单列索引
最常用场景:为高频查询字段(如 Email、Status)加索引提升查询速度。
示例:为
User.Email添加普通索引
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasIndex(u => u.Email); // 默认非唯一
}
生成的迁移代码会调用
CreateIndex,数据库执行后生效。
唯一索引与多列索引
防止重复数据或组合查询优化时非常实用。
唯一索引:加IsUnique()多列索引:传入匿名对象或元组,顺序影响查询效率
// 唯一索引:确保邮箱不重复
modelBuilder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
// 多列索引:按 (Status, CreatedAt) 查询快
modelBuilder.Entity<Order>()
.HasIndex(o => new { o.Status, o.CreatedAt });
高级选项:过滤索引与包含列(SQL Server)
仅 SQL Server 支持,适合稀疏数据或覆盖查询场景。
过滤索引:只对满足条件的数据建索引(如Status = 'Active') 包含列:把非键列加入索引叶节点,避免回表
modelBuilder.Entity<User>()
.HasIndex(u => u.Email)
.HasFilter("[Status] = 'Active'") // SQL 表达式
.IncludeProperties(u => u.FirstName); // 包含 FirstName 列
注意:
HasFilter和
IncludeProperties是 SQL Server 特有,其他数据库迁移会忽略或报错。
索引命名与性能提醒
EF Core 默认为索引生成名称(如
IX_Users_Email),也可手动指定:
.HasIndex(u => u.Email)
.HasName("IX_Users_Email_Verified");
小建议:
别盲目加索引——写多读少的表加索引反而拖慢插入/更新 复合索引注意字段顺序:等值查询字段放前,范围查询字段放后(如WHERE Status = 1 AND CreatedAt > '2024',索引应为
(Status, CreatedAt)) 迁移前用
dotnet ef migrations script查看实际 SQL,确认索引是否符合预期
基本上就这些。HasIndex 看似简单,但结合业务查询模式合理设计,才能真正提升性能。
