回答:
Entity Framework 6.1以降では、モデルでこの属性を使用できます。
[Index(IsUnique=true)]
この名前空間で見つけることができます:
using System.ComponentModel.DataAnnotations.Schema;
モデルフィールドが文字列の場合は、SQL Serverでnvarchar(MAX)に設定されていないことを確認してください。そうしないと、Entity Framework Code Firstでこのエラーが表示されます。
テーブル 'dbo.y'の列 'x'は、インデックスのキー列として使用するには無効なタイプです。
その理由は次のとおりです。
SQL Serverは、すべてのインデックスキー列の最大合計サイズの900バイトの制限を保持しています。」
(from:http : //msdn.microsoft.com/en-us/library/ms191241.aspx)
これを解決するには、モデルに最大文字列長を設定します。
[StringLength(450)]
EF CF 6.1以降では、モデルは次のようになります。
public class User
{
public int UserId{get;set;}
[StringLength(450)]
[Index(IsUnique=true)]
public string UserName{get;set;}
}
更新:
Fluentを使用する場合:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
// ....
Property(x => x.Name).IsRequired().HasMaxLength(450).HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }));
}
}
そしてあなたのmodelBuilderで使用してください:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// ...
modelBuilder.Configurations.Add(new UserMap());
// ...
}
アップデート2
EntityFrameworkCoreについては、次のトピックも参照してください。https://github.com/aspnet/EntityFrameworkCore/issues/1698
アップデート3
EF6.2の場合:https : //github.com/aspnet/EntityFramework6/issues/274
アップデート4
ASP.NET Core Mvc 2.2とEF Core:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Unique { get; set; }
"There are no significant differences between creating a UNIQUE constraint and creating a unique index that is independent of a constraint. Data validation occurs in the same manner, and the query optimizer does not differentiate between a unique index created by a constraint or manually created. However, creating a UNIQUE constraint on the column makes the objective of the index clear."
EFは、キー以外の一意の列をサポートしていません。EF移行を使用している場合は、EFにUserName
列に一意のインデックスを作成することができます(アノテーションではなく、移行コードで)。ただし、一意性はデータベースでのみ適用されます。重複する値を保存しようとすると、データベースによって起動された例外(制約違反)をキャッチする必要があります。
コードから、POCOを使用していることが明らかになります。別のキーを持つ必要はありません。juFoの提案に従ってインデックスを追加できます。
UserNameプロパティに起因するのではなくFluent APIを使用する場合、列注釈は次のようになります。
this.Property(p => p.UserName)
.HasColumnAnnotation("Index", new IndexAnnotation(new[] {
new IndexAttribute("Index") { IsUnique = true }
}
));
これにより、次のSQLスクリプトが作成されます。
CREATE UNIQUE NONCLUSTERED INDEX [Index] ON [dbo].[Users]
(
[UserName] ASC
)
WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
同じUserNameを持つ複数のユーザーを挿入しようとすると、次のメッセージでDbUpdateExceptionが発生します。
Cannot insert duplicate key row in object 'dbo.Users' with unique index 'Index'.
The duplicate key value is (...).
The statement has been terminated.
繰り返しになりますが、列アノテーションはバージョン6.1より前のEntity Frameworkでは使用できません。
FluentAPIを使用するEF 6.2では、次を使用できますHasIndex()
modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
EF4.3のソリューション
一意のユーザー名
次のように列にデータ注釈を追加します:
[Index(IsUnique = true)]
[MaxLength(255)] // for code-first implementations
public string UserName{get;set;}
一意のID 、列に装飾[Key]を追加して完了しました。ここで説明されているのと同じソリューション:https : //msdn.microsoft.com/en-gb/data/jj591583.aspx
IE:
[Key]
public int UserId{get;set;}
別の答え
データ注釈の使用
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("UserId")]
マッピングの使用
mb.Entity<User>()
.HasKey(i => i.UserId);
mb.User<User>()
.Property(i => i.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.HasColumnName("UserId");
Key
属性を追加すると、UserName
プロパティがUserName
データベースの主キーになります。UserId
プロパティのみをKey
属性でマークする必要があります。このソリューションは、プログラミング側で「正しい」動作を提供すると同時に、不適切なデータベース設計を提供します。