How to create index in Entity Framework 6.2 with fluent configuration

Is there a way to create an index on a property/column using fluent configuration, instead of using the new IndexAttribute ?

108827 次浏览

如果你不想在你的 POCO 上使用属性,那么你可以这样做:

context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");

可以在自定义 DbInitializer派生类中执行此语句。但是我不知道任何 Fluent API 的方法来实现这一点。

目前还没有用于通过连贯 API 创建索引的 “一流的支持”,但是您可以通过连贯 API 将属性标记为具有来自注释 API 的属性。这将允许您通过一个流畅的接口添加 Index属性。

以下是来自 EF 问题站点的工作项的一些示例。

在单个列上创建索引:

modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute()));

单列上的多个索引:

modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute("Index1"),
new IndexAttribute("Index2") { IsUnique = true }
}));

多列索引:

modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty1)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 1)));


modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty2)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 2)));

使用上述技术将导致在您的 Up()函数中为您自动创建 .CreateIndex()调用,当您构建下一次迁移时(或者如果您没有使用迁移,则在数据库中自动创建)。

可以使用 INDEX 数据注释 代码第一数据注释

我已经创建了一些扩展方法,并将它们包装在一个 nuget 包中,以使其更加简单。

安装 EntityFramework.IndexingExtensions核心软件包。

然后你可以做以下事情:

public class MyDataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasIndex("IX_Customers_Name",          // Provide the index name.
e => e.Property(x => x.LastName),   // Specify at least one column.
e => e.Property(x => x.FirstName))  // Multiple columns as desired.


.HasIndex("IX_Customers_EmailAddress",  // Supports fluent chaining for more indexes.
IndexOptions.Unique,                // Supports flags for unique and clustered.
e => e.Property(x => x.EmailAddress));
}
}

项目和源代码在这里 。请欣赏!

实体框架6

Property(c => c.MyColumn)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_MyIndex")));

并添加使用:

using System.Data.Entity.Infrastructure.Annotations;
using System.ComponentModel.DataAnnotations.Schema;

没有明确的名称:

[Index]
public int Rating { get; set; }

有一个特定的名字:

[Index("PostRatingIndex")]
public int Rating { get; set; }

从 EF 6.1开始支持属性 [Index]
对唯一索引使用 [Index(IsUnique = true)]
这里是来自微软的链接

public class User
{
public int UserId { get; set; }


[Index(IsUnique = true)]
[StringLength(200)]
public string Username { get; set; }


public string DisplayName { get; set; }
}

为了避免额外的代码,我写了一个在流畅的 EF 中使用的扩展方法:

public static PrimitivePropertyConfiguration HasIndexAnnotation(
this PrimitivePropertyConfiguration primitivePropertyConfiguration,
IndexAttribute indexAttribute = null
)
{
indexAttribute = indexAttribute ?? new IndexAttribute();


return primitivePropertyConfiguration
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(indexAttribute)
);
}

然后像这样使用它:

Property(t => t.CardNo)
.HasIndexAnnotation();

如果 index 需要一些配置,则如下所示:

Property(t => t.CardNo)
.HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });

2017年10月26日实体框架6.2是 正式释放。 它包括一个 可能性,可以通过 FluentAPI 轻松地定义索引。它是在测试版中使用的已经是 宣布的6.2。

现在您可以使用 HasIndex()方法,如果 IsUnique()应该是唯一索引,则可以使用 IsUnique()

只是一个小比较(之前/之后)的例子:

// before
modelBuilder.Entity<Person>()
.Property(e => e.Name)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute { IsUnique = true }));


// after
modelBuilder.Entity<Person>()
.HasIndex(p => p.Name)
.IsUnique();


// multi column index
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.Name, p.Firstname })
.IsUnique();

还可以将索引标记为与 .IsClustered()聚集在一起。


编辑 # 1

添加了多列索引的示例以及如何将索引标记为聚集的附加信息。


编辑 # 2

作为附加信息,在 EF Core 2.1中,它与现在的 EF 6.2完全一样。
这里 是 MS 文件作为参考。

你可以用这个

//索引

 this.HasIndex(e => e.IsActive)
.HasName("IX_IsActive");

或者

  this.Property(e => e.IsActive).HasColumnAnnotation(
"Index",
new IndexAnnotation(new IndexAttribute("IX_IsActive")));

目前,. net core的节目将包括:

[Index(nameof(AdvId), IsUnique = true)]
public class tblAdvertisement
{
public int Id { get; set; }
public int AdvId { get; set; }
public DateTime Created { get; set; }
}

因此,属性集在 class 上,而不是在 member 上:

protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_Advertisements_AdvId",
table: "Advertisements",
column: "AdvId",
unique: true);
}


protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Advertisements_AdvId",
table: "Advertisements");


}