我有一个必须是唯一的“名称”列。没有外国钥匙或类似的东西。
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(); //???
}
}
注意:与EF 6相关
您可以使用所提到的IndexAttribute
但with 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)
Fluent API
to specify indexes without additional tricks.
HasIndex
allows to define it:
modelBuilder
.Entity<Person>()
.HasIndex(x => x.Name);
因此它返回qazxsw poi对象,您可以将其用于进一步的索引配置(即唯一性):
IndexBuilder
根据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();
这个答案仅包含其他信息,因为已有很好的答案。
如果要在索引中包含多个唯一字段,可以通过添加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
}
}
)
);
。
在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();
您可以在迁移文件中创建唯一索引。
在包管理器中:
这将在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");
}
对我来说,使用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);