实体框架6中的多列索引



我正在使用Entity Framework 6.0开发一个遗留系统,并且有一个新的要求,允许用户在已删除的记录上重复使用以前使用过的代码。为此,我添加了一个可以为null的DeletedDate列和一个唯一的索引,该索引将代码和删除日期组合在一起。

为了实现这一点,我在DataContext上的OnModelCreating方法中添加了以下代码。

modelBuilder.Entity<MyEntity>().HasIndex(e => new {e.Code, e.DeletedDate}).IsUnique();

这很有效。但后来我们有一个类似的要求,用户希望重用名称和代码,而不一定要一起使用。所以我想我可以这么做:

modelBuilder.Entity<MyEntity>().HasIndex(e => new {e.Name, e.DeletedDate}).IsUnique();
modelBuilder.Entity<MyEntity>().HasIndex(e => new {e.Code, e.DeletedDate}).IsUnique();

这会编译、运行并不会引发任何错误,但当我检查数据库上的结果索引时,第一个索引总是会从其定义中丢失DeletedDate列,从而仅在Name上创建一个唯一的索引。我可以在SQL Server中手动添加DeletedDate列,但EF根本不会为我做这件事

这是一个bug吗?还是有充分的理由让我不能这么做?也许更重要的是,有没有一种方法可以首先在EF代码中实现这一点?

我们使用的是SQL Server 2019。

我解决这个问题的方法是在每个属性上使用Index属性。

[Index("IX_Name_DeletedDate", 1, IsUnique = true)]
public string Name { get; set;}
[Index("IX_Code_DeletedDate", 1, IsUnique = true)]
public string Code { get; set;}
[Index("IX_Code_DeletedDate", 2, IsUnique = true)]
[Index("IX_UniqueIdentity_DeletedDate", 2, IsUnique = true)]
public DateTime? DeletedDate { get; set; }

使用流利的语法无法做到这一点似乎是EF 6.0 中的一个缺陷

最新更新