如何在Entity Framework 6.1 Code First模型中更改聚簇索引并将其应用于Azure数据库

Dav*_*pko 6 entity-framework azure

使用Entity Framework 6.1代码优先模型,将表上的聚簇索引从默认ID更改为另一组列的最佳方法是什么.Azure不允许没有聚簇索引的表.

  public partial class UserProfile 
  {
    public override Guid ID { get; set; }

    [Index( "CI_UserProfiles_UserID", IsClustered = true)]
    public Guid UserID { get; set; }

    [Required]
    public Guid FieldID { get; set; }

    [Required]
    [StringLength(400)]
    public string Value { get; set; }
 }
Run Code Online (Sandbox Code Playgroud)

在表上UserProfiles,ID已经是主键和聚簇索引.添加

[Index( "CI_UserProfiles_UserID", IsClustered = true)] 
Run Code Online (Sandbox Code Playgroud)

到UserID创建此迁移:

CreateIndex("dbo.UserProfiles", "UserID", clustered: true, name: "IX_UserProfiles_UserID");
Run Code Online (Sandbox Code Playgroud)

执行迁移会生成以下错误:

无法在表'dbo.UserProfiles'上创建多个聚簇索引.删除现有的聚簇索引"PK_dbo.UserProfiles",然后再创建另一个.

Cod*_*und 6

要解决您的问题,在生成迁移文件后,必须通过将参数false值赋值为for来禁用主键的聚簇索引来修改生成的代码.clusteredPrimaryKey

修改后,您必须在迁移文件中包含以下内容:

CreateTable(
    "dbo.UserProfiles",
    c => new
        {
            Id = c.Guid(nullable: false),
            UserID = c.Guid(nullable: false),
            FieldID = c.Guid(nullable: false),
            Value = c.String(nullable: false, maxLength: 400),
        })
    .PrimaryKey(t => t.Id, clustered: false)
    .Index(t => t.UserID, clustered: true, name: "CI_UserProfiles_UserID");
Run Code Online (Sandbox Code Playgroud)

这不是OnModelCreating通过使用像Manish Kumar所说的Fluent API 在方法中完成的,而是在迁移文件中.使用Add-Migration命令时创建的文件.

现有数据库

正如您在评论中所说,您的数据库已经存在.执行Add-Migration命令后,您的方法将在您的DbMigration文件中包含以下行Up():

public override void Up()
{
    CreateIndex("dbo.UserProfiles", "UserID", clustered: true, name: "CI_UserProfiles_UserID");
}
Run Code Online (Sandbox Code Playgroud)

您必须修改Up()方法才能拥有此代码:

public override void Up()
{
    this.Sql("ALTER TABLE dbo.UserProfiles DROP CONSTRAINT \"PK_dbo.UserProfiles\"");
    this.Sql("ALTER TABLE dbo.UserProfiles ADD CONSTRAINT \"PK_dbo.UserProfiles\" PRIMARY KEY NONCLUSTERED (Id);");
    this.CreateIndex("dbo.UserProfiles", "UserID", clustered: true, name: "CI_UserProfiles_UserID");
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我假设创建的聚簇索引在数据库中名为PK_dbo.UserProfiles.如果没有,那么在这个地方放正确的名称.


小智 1

您需要从当前的 PK“ID”中删除现有的聚集索引,该索引是默认为代码中的任何“KEY”属性创建的。可以使用 Fluent API 来完成:

.Primarykey(x=>x.ID,clustered:false)
Run Code Online (Sandbox Code Playgroud)

从 ID 中删除现有聚集索引后,在 UserID 上添加聚集索引的迁移应该会顺利进行。