131

Entity Framework 4.3 と Code Fist を使用しています。

クラスがあります

public class User
{
   public int UserId{get;set;}
   public string UserName{get;set;}
}

データベーステーブルを作成するときに UserName が一意でなければならないことを Entity Framework に伝えるにはどうすればよいですか? 可能であれば、構成ファイルの代わりにデータ注釈を使用したいと思います。

4

6 に答える 6

294

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 バイトの制限を保持しています。」

(から: 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 } }));
    }
  }

そしてあなたのモデルビルダーで使用してください:

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; }
于 2014-04-14T08:51:59.367 に答える
28

EF は、キー以外の一意の列をサポートしていません。EF 移行を使用している場合は、EF に強制的にUserName列に一意のインデックスを作成させることができますが (注釈ではなく、移行コードで)、一意性はデータベースでのみ適用されます。重複した値を保存しようとすると、データベースによって発生した例外 (制約違反) をキャッチする必要があります。

于 2012-05-16T08:36:17.630 に答える
11

コードから、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 では、列の注釈は使用できません。

于 2014-04-17T15:32:44.583 に答える
5

Entity Framework 6.1 (現在はベータ版) では、Code First Migrations で (一意の) インデックスが自動的に作成されるインデックス プロパティに注釈を付けるための IndexAttribute がサポートされることに注意してください。

于 2014-03-09T19:58:15.987 に答える
-12

EF4.3 のソリューション

一意のユーザー名

次のように列にデータ注釈を追加します。

 [Index(IsUnique = true)]
 [MaxLength(255)] // for code-first implementations
 public string UserName{get;set;}

Unique ID 、装飾 [Key] を列に追加して完了しました。ここで説明されているのと同じソリューション: https://msdn.microsoft.com/en-gb/data/jj591583.aspx

いいえ:

[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");
于 2012-05-23T12:40:22.637 に答える