「名前」という列があり、それは一意である必要があります。外部キーなどはありません。
EF 6.1は、アノテーションを介したこのようなインデックスの作成を最終的にサポートします。それは既に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(); //???
}
}
Anatoliiの答えに基づいて、一意のインデックスをより流settingに設定するための拡張方法を次に示します。
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
のインデックスも必要だとしましょう。
wrongそれを行う方法は、newthis.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
}
}
)
);
_
最後に、インデックス/ユニークのソート順も変更したい場合、以下を見ることができます:
EFの新しいバージョン6.2では、HasIndex
メソッドを使用できます。
modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique(true);
modelBuilder.Entity<User>().HasIndex(user => user.UserName).IsUnique(true);
EF Coreのアップデート:
modelBuilder.Entity<User>()
.HasIndex(b => b.Email)
.IsUnique();
modelBuilder.Entity<User>()
.HasIndex(b => b.UserName)
.IsUnique();
移行ファイルに一意のインデックスを作成できます。
パッケージマネージャーで:
これにより、Migrationsフォルダーにタイムスタンプ付きの新しいファイルが作成されます。このクラスには、インデックスの作成に使用できるUpおよびDownメソッドがあります。
public override void Up()
{
// ...
CreateIndex("tableName", "columnName", unique: true, name: "myIndex");
}
public override void Down()
{
// ...
DropIndex("tableName", "myIndex");
}
移行を実行するには、パッケージマネージャーでUpdate-Databaseと入力します。
また、テーブルを作成する移行の一部としてインデックスを追加することもできます。
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);
私にとって、MVC 5とEF 6を使用して、キーポイントは、インデックスを配置する文字列プロパティの長さを指定することでした。
protected override void OnModelCreating(DbModelBuilder modelBuilder){
//More stuff
modelBuilder.Entity<Device>().Property(c => c.Name).HasColumnType("nvarchar").HasMaxLength(50);
modelBuilder.Entity<Device>().HasIndex(c => c.Name).IsUnique(true);
}