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

Joh*_*ohn 38 .net c# entity-framework fluent-interface entity-framework-6

我有一个列"名称",必须是unqiue.没有外国钥匙或类似的东西.

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();  //???
    }
}
Run Code Online (Sandbox Code Playgroud)

Ana*_*uza 58

注意:与EF 6相关

您可以IndexAttribute像上面提到的那样使用,Fluent API而不是使用DataAnnotations哪种方法:

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

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


更新:实体框架核心

在最新的EF Core版本中,您可以依赖于Fluent API指定索引而无需额外的技巧.
HasIndex允许定义它:

modelBuilder 
    .Entity<Person>()
    .HasIndex(x => x.Name);
Run Code Online (Sandbox Code Playgroud)

因此,它会重新调整IndexBuilder对象,您可以将其用于进一步的索引配置(即唯一性):

modelBuilder 
    .Entity<Person>()
    .HasIndex(x => x.Name)
    .IsUnique();
Run Code Online (Sandbox Code Playgroud)


Gei*_*erg 36

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

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

用法:

modelBuilder 
    .Entity<Person>() 
    .Property(t => t.Name)
    .IsUnique();
Run Code Online (Sandbox Code Playgroud)

将生成迁移,例如:

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" });
    }
}
Run Code Online (Sandbox Code Playgroud)


Max*_*ime 28

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

如果要在索引中包含多个唯一字段,可以通过添加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
            }

        )
    );
Run Code Online (Sandbox Code Playgroud)

现在,假设您还想要一个索引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
                }
            }
        )
    );
Run Code Online (Sandbox Code Playgroud)

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

如何使用Fluent API在具有ASC/DESC排序的多个列上添加索引?.


Soh*_*deh 8

6.2的新版EF中,您可以使用以下HasIndex方法:

 modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique(true);
 modelBuilder.Entity<User>().HasIndex(user => user.UserName).IsUnique(true);
Run Code Online (Sandbox Code Playgroud)

更新EF Core:

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

 modelBuilder.Entity<User>()
        .HasIndex(b => b.UserName)
        .IsUnique();
Run Code Online (Sandbox Code Playgroud)

Microsoft Docs - EF核心索引