Fluent Api 未创建完全正确的迁移文件内容,因此未将唯一索引应用于数据库

Fluent Api is NOT creating a fully correct Migration file content, so that unique indexes are not being applied to the database

(标题已更改,更改见下方编辑)

当前项目:

当我使用 fluent API 定义一个 table 有两个唯一索引时:

Property(x => x.UserId)
  .HasColumnOrder(1)
  .HasColumnName("UserId")
  .HasColumnType("uniqueidentifier")
  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
  .HasColumnAnnotation(
    "UserId", 
    new IndexAnnotation(
      new IndexAttribute("IX_UserId") { 
        IsUnique = true 
      }
    )
  )
  .IsRequired();
Property(x => x.UserName)
  .HasColumnOrder(2)
  .HasColumnName("UserName")
  .HasColumnType("nvarchar")
  .HasMaxLength(256)
  .HasColumnAnnotation(
    "Username", 
    new IndexAnnotation(
      new IndexAttribute("IX_Username") { 
        IsUnique = true 
      }
    )
  )
  .IsRequired();

在迁移文件中看到正确的迁移条目:

UserId = c.Guid(
  nullable: false, 
  identity: true, 
  defaultValueSql: "NEWID()",
  annotations: new Dictionary<string, AnnotationValues> {
    { 
      "UserId", 
      new AnnotationValues(
        oldValue: null, 
        newValue: "IndexAnnotation: { 
          Name: IX_UserId, 
          IsUnique: True 
        }"
      ) 
    } 
  }
),
UserName = c.String(
  nullable: false, 
  maxLength: 256, 
  annotations: new Dictionary<string, AnnotationValues> {
    { 
      "Username", 
      new AnnotationValues(
        oldValue: null, 
        newValue: "IndexAnnotation: { 
          Name: IX_Username, 
          IsUnique: True 
        }"
      ) 
    } 
  }
),

然而,当我检查数据库并查看 table 的 keys/indexes 时,我注意到 UserId 索引是 而不是 命名为 IX_UserId(它被称为相当默认的 PK_dbo.User),并且 UserName 根本不存在 index/uniqueness .我需要在 SQL Management Studio 中手动创建它。

虽然 EF Fluent API 能够创建看起来像正确的迁移文件,并具有所有正确的属性,但这并没有 运行 完全成功地迁移到数据库,只需要创建默认索引(迁移文件中指定的所有索引信息都被完全忽略,以支持主键的默认装饰)。

谁能解释一下我哪里出错了?


编辑:

嗯……this other example 就 运行,也许是我哪里出错了?据此,我的 Fluent API 应该是这样的:

Property(x => x.UserId)
  .HasColumnOrder(1)
  .HasColumnName("UserId")
  .HasColumnType("uniqueidentifier")
  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
  .HasColumnAnnotation(
    "UserId", 
    new IndexAnnotation(
      new IndexAttribute("IX_UserId") { 
        IsUnique = true,
        Order = 1
      }
    )
  )
  .IsRequired();
Property(x => x.UserName)
  .HasColumnOrder(2)
  .HasColumnName("UserName")
  .HasColumnType("nvarchar")
  .HasMaxLength(256)
  .HasColumnAnnotation(
    "Username", 
    new IndexAnnotation(
      new IndexAttribute(),
      new IndexAttribute("IX_Username") { 
        IsUnique = true 
        Order = 2
      }
    )
  )
  .IsRequired();

我读的其他 post 正确吗?


编辑 2:

Uhhhh...我刚刚发现使用了正确的索引名称 ,但仅在这些键作为 外键 存在的地方其他 tables。因此,无论 UserId 作为外键存在于其他 table 中,它都具有正确的索引名称 IX_UserId,即使我的 Fluent API 从未描述过该外键的索引输入 table.

威士忌。探戈。狐步舞。


编辑 3:

Fluent API NOT 创建正确的迁移文件。刚刚对比了一下其他table的外键和迁移文件,其他table的外键明显有如下内容:

.Index(t => t.UserId)
.Index(t => t.CourseId);

是的,Fluent API 没有构建正确的迁移文件,因为它缺少一大堆 .Index() 主键等条目。

查看 HasColumnAnnotation 方法的文档,它说:

我的猜测是您没有使用有效的 C#/EDM 注释名称。尝试使用 IndexAnnotation.AnnotationName 常量作为索引的参数:

using System.Data.Entity.Infrastructure.Annotations;

...

Property(x => x.UserId)
    ...
    .HasColumnAnnotation(
         IndexAnnotation.AnnotationName, <-- this is the valid annotation name. 
          new ndexAttribute("Ix_UserId") {IsUnique = true});

这是一个等于 "Index" 的常量值,但我怀疑这可能是导致您出现问题的原因。

希望对您有所帮助!