使用Entity Framework 6.1流畅的API创建唯一索引

问题描述 投票:38回答:6

我有一个必须是唯一的“名称”列。没有外国钥匙或类似的东西。

EF 6.1最终支持通过Annotations创建此类索引。已在SO上讨论过这个问题。但它似乎只能通过类中的注释来完成。如何仅使用Fluent API执行此操作?

像这样的东西:

public class PersonConfiguration : EntityTypeConfiguration<Person>
{
    public PersonConfiguration()
    {
        HasKey(p => p.Id);
        Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        //not possible?
        Index(p => p.Name).IsUnique();  //???
    }
}
c# .net entity-framework entity-framework-6 fluent-interface
6个回答
58
投票

注意:与EF 6相关

您可以使用所提到的IndexAttributewith Fluent API而不是DataAnnotations可以解决这个问题:

modelBuilder 
    .Entity<Person>() 
    .Property(t => t.Name) 
    .HasColumnAnnotation( 
        "Index",  
        new IndexAnnotation(new IndexAttribute("IX_Name") { IsUnique = true }));

不幸的是,没有其他方法可以使用Fluent API创建唯一索引。关于此功能有一个未解决的问题:Unique Constraints (Unique Indexes)


UPDATE: Entity Framework Core

In the latest EF Core release you can rely on Fluent API to specify indexes without additional tricks.
HasIndex allows to define it:
modelBuilder 
    .Entity<Person>()
    .HasIndex(x => x.Name);

因此它返回qazxsw poi对象,您可以将其用于进一步的索引配置(即唯一性):

IndexBuilder

36
投票

根据Anatolii的回答,这里有一个更流利地设置唯一索引的扩展方法:

modelBuilder 
    .Entity<Person>()
    .HasIndex(x => x.Name)
    .IsUnique();

用法:

public static class MappingExtensions
{
    public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration)
    {
        return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true }));
    }
}

将生成迁移,例如:

modelBuilder 
    .Entity<Person>() 
    .Property(t => t.Name)
    .IsUnique();

28
投票

这个答案仅包含其他信息,因为已有很好的答案。

如果要在索引中包含多个唯一字段,可以通过添加public partial class Add_unique_index : DbMigration { public override void Up() { CreateIndex("dbo.Person", "Name", unique: true); } public override void Down() { DropIndex("dbo.Person", new[] { "Name" }); } } 属性来实现。您还必须确保在所有属性中使用相同的索引名称(请参阅下面的Order)。

uniqueIndex

现在,让我们说你也想要一个关于string uniqueIndex = "UN_TableName"; this.Property(t => t.PropertyOne) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute(uniqueIndex) { IsUnique = true, Order = 1 } ) ); this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute(uniqueIndex) { IsUnique = true, Order = 2 } ) ); 的索引。

这样做的错误方法是用PropertyTwo开始新的一行,因为它会取消您的唯一索引。

必须同时定义所有索引(索引和唯一)。这将是正确的方法:

this.Property(t => t.PropertyTwo)

最后,如果您还想更改索引/唯一的排序顺序,您可以看到:

this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation(new[] { new IndexAttribute(), // This is the index new IndexAttribute(uniqueIndex) // This is the Unique made earlier { IsUnique = true, Order = 2 } } ) );


8
投票

在6.2的新版EF中,您可以使用How to add an index on multiple columns with ASC/DESC sort using the Fluent API ?方法:

HasIndex

更新EF Core:

 modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique(true);
 modelBuilder.Entity<User>().HasIndex(user => user.UserName).IsUnique(true);

modelBuilder.Entity<User>() .HasIndex(b => b.Email) .IsUnique(); modelBuilder.Entity<User>() .HasIndex(b => b.UserName) .IsUnique();


4
投票

您可以在迁移文件中创建唯一索引。

在包管理器中:

  1. 启用的迁移
  2. 添加迁移InitialMigration

这将在Migrations文件夹中创建一个带时间戳的新文件。该类将具有可用于创建索引的Up和Down方法:

Microsoft Docs - EF Core Indexes

在包管理器中运行迁移类型Update-Database。

您还可以将索引添加为创建表的迁移的一部分:

public override void Up()
{
    // ... 
    CreateIndex("tableName", "columnName", unique: true, name: "myIndex");
}

public override void Down()
{
    // ...
    DropIndex("tableName", "myIndex");
}

0
投票

对我来说,使用MVC 5和EF 6,关键点是在字符串属性上指定我想要放置索引的长度。

CreateTable(
    "dbo.Products",
    c => new
        {
            ProductId = c.Int(nullable: false, identity: true),
            ProductName = c.String(nullable: false, maxLength: 256),
        })
    .Index(c => c.ProductName, name: "IX_Products_ProductName", unique: true)
    .PrimaryKey(t => t.ProductId);
© www.soinside.com 2019 - 2024. All rights reserved.