Entity Framework Core多过滤唯一索引被覆盖,如何同时生效?
问题描述
此前曾遇到数据库重复值问题,因此添加了一些复合约束。今日发现仍可向数据库中添加重复记录,通过Fluent API配置的以下两个过滤唯一索引仅其中一个生效:
//限制单个用户仅存在1条待处理(SaleStatus=0)订单——未生效 modelBuilder.Entity<Sale>().HasIndex(e => new { e.SaleStatus, e.UserObjectId }).IsUnique().HasFilter("[SaleStatus] = 0"); //限制单个用户仅存在1条已激活(SaleStatus=5)订单——正常生效 modelBuilder.Entity<Sale>().HasIndex(e => new { e.SaleStatus, e.UserObjectId }).IsUnique().HasFilter("[SaleStatus] = 5");
尝试调整配置顺序、分开执行迁移,但始终只有一个索引生效。请问如何确保两个过滤唯一索引同时生效?
解决方案
问题出在EF Core的默认索引命名规则上:当你基于相同的列组合(SaleStatus + UserObjectId)创建索引时,EF Core会自动生成相同的索引名称,导致第二个索引覆盖了第一个,最终只有一个索引被创建到数据库中。
解决方法很简单,给每个过滤索引指定唯一的名称,通过HasName方法明确区分:
// 待处理订单唯一索引,指定自定义唯一名称 modelBuilder.Entity<Sale>() .HasIndex(e => new { e.SaleStatus, e.UserObjectId }) .IsUnique() .HasFilter("[SaleStatus] = 0") .HasName("IX_Sales_Pending_User"); // 已激活订单唯一索引,指定不同的自定义名称 modelBuilder.Entity<Sale>() .HasIndex(e => new { e.SaleStatus, e.UserObjectId }) .IsUnique() .HasFilter("[SaleStatus] = 5") .HasName("IX_Sales_Active_User");
修改完成后,重新生成并执行迁移,数据库中就会同时存在两个独立的过滤唯一索引,分别实现对应的约束逻辑。
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

