Entity Framework kodu ilk benzersiz sütun


114

Entity Framework 4.3 kullanıyorum ve Code Fist kullanıyorum.

Sınıfım var

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

Entity Framework'e, veritabanı tablosu oluştururken UserName'in benzersiz olması gerektiğini nasıl söyleyebilirim? Mümkünse yapılandırma dosyası yerine veri açıklamalarını kullanmayı tercih ederim.

Yanıtlar:


258

Entity Framework 6.1+ sürümünde bu özniteliği modelinizde kullanabilirsiniz:

[Index(IsUnique=true)]

Bunu şu ad alanında bulabilirsiniz:

using System.ComponentModel.DataAnnotations.Schema;

Model alanınız bir dizeyse, SQL Server'da nvarchar (MAX) olarak ayarlanmadığından emin olun, aksi takdirde Entity Framework Code First ile bu hatayı görürsünüz:

'Dbo.y' tablosundaki 'x' sütunu, bir dizinde anahtar sütun olarak kullanım için geçersiz olan bir türden.

Nedeni şudur:

SQL Server, tüm dizin anahtarı sütunlarının maksimum toplam boyutu için 900 baytlık sınırı korur. "

(from: http://msdn.microsoft.com/en-us/library/ms191241.aspx )

Bunu, modelinize bir maksimum dizi uzunluğu ayarlayarak çözebilirsiniz:

[StringLength(450)]

Modeliniz şimdi EF CF 6.1+ sürümünde şöyle görünecek:

public class User
{
   public int UserId{get;set;}
   [StringLength(450)]
   [Index(IsUnique=true)]
   public string UserName{get;set;}
}

Güncelleme:

Fluent kullanıyorsanız:

  public class UserMap : EntityTypeConfiguration<User>
  {
    public UserMap()
    {
      // ....
      Property(x => x.Name).IsRequired().HasMaxLength(450).HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }));
    }
  }

ve modelBuilder'ınızda kullanın:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  // ...
  modelBuilder.Configurations.Add(new UserMap());
  // ...
}

Güncelleme 2

EntityFrameworkCore için ayrıca şu konuya bakın: https://github.com/aspnet/EntityFrameworkCore/issues/1698

Güncelleme 3

EF6.2 için bkz: https://github.com/aspnet/EntityFramework6/issues/274

Güncelleme 4

EF Core ile ASP.NET Core Mvc 2.2:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Unique { get; set; }

23
Bu adamın eski gönderisine bazı alakalı güncel bilgilerle yanıt verdiğiniz için teşekkürler!
Jim Yarbro

3
neden bir indeks, neden sadece bir kısıtlama olmasın?
John Henckel

2
İndeks ve kontraint sorusunu yanıtlamak için ... MSDN: "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." msdn.microsoft.com/en-us/library/ms187019.aspx
user919426

3
Not; Entity Framework Core 1.0.0-preview2-final'de bir veri ek açıklama yöntemi kullanılamıyor - docs.efproject.net/en/latest/modeling/…
Edward Comeau

26

EF, anahtarlar dışında benzersiz sütunları desteklemez. EF Geçişlerini kullanıyorsanız, EF'yi UserNamesütun üzerinde benzersiz dizin oluşturmaya zorlayabilirsiniz (geçiş kodunda, herhangi bir ek açıklamayla değil) ancak benzersizlik yalnızca veritabanında uygulanacaktır. Yinelenen değeri kaydetmeye çalışırsanız, veritabanı tarafından tetiklenen istisnayı (kısıtlama ihlali) yakalamanız gerekir.


1
Tam olarak aradığım buydu! Göçleri kullanarak bu tür kısıtlamaları eklemenin mümkün olup olmadığını merak ediyordum.
Alex Jorgenson

@Ladislav Mrnka: Bu, Tohum yöntemiyle de mümkün mü?
Raheel Khan 01

2
Bir örnek vermek ister misiniz? Teşekkürler!
Zero3

10

Kodunuzdan POCO kullandığınız anlaşılıyor. Başka bir anahtara sahip olmak gereksizdir: juFo'nun önerdiği şekilde bir dizin ekleyebilirsiniz .
UserName özelliğini ilişkilendirmek yerine Fluent API kullanıyorsanız, sütun ek açıklamanız şöyle görünmelidir:

this.Property(p => p.UserName)
    .HasColumnAnnotation("Index", new IndexAnnotation(new[] { 
        new IndexAttribute("Index") { IsUnique = true } 
    }
));

Bu, aşağıdaki SQL komut dosyasını oluşturacaktır:

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]

Aynı UserName'e sahip birden fazla Kullanıcı eklemeye çalışırsanız, aşağıdaki mesajla bir DbUpdateException alırsınız:

Cannot insert duplicate key row in object 'dbo.Users' with unique index 'Index'. 
The duplicate key value is (...).
The statement has been terminated.

Yine, 6.1 sürümünden önceki Entity Framework'te sütun açıklamaları kullanılamaz.


Yapılandırmayı kullanarak birden çok sütun içeren bir dizin oluşturmaya ne dersiniz?
FindOutIslamNow

Biri UserName'de, diğeri nedir?
Alexander Christov

5

Entity Framework 6.1'de (şu anda beta sürümünde) IndexAttribute'u, Code First Migrations'ta otomatik olarak (benzersiz) bir dizine neden olacak dizin özelliklerine açıklama eklemek için destekleyeceğini unutmayın.


2

FluentAPI kullanan EF 6.2'de kullanabilirsinizHasIndex()

modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();

-13

EF4.3 için Çözüm

Benzersiz Kullanıcı Adı

Sütunun üzerine veri ek açıklamasını şu şekilde ekleyin:

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

Benzersiz Kimlik , sütunuma dekorasyon [Anahtar] ekledim ve tamamladım. Burada açıklananla aynı çözüm: https://msdn.microsoft.com/en-gb/data/jj591583.aspx

IE:

[Key]
public int UserId{get;set;}

Alternatif cevaplar

veri açıklamasını kullanma

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("UserId")]

haritalama kullanarak

  mb.Entity<User>()
            .HasKey(i => i.UserId);
        mb.User<User>()
          .Property(i => i.UserId)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
          .HasColumnName("UserId");

25
Bu çözüme dikkat edin. Özelliğe Keyöznitelik eklemek, özelliğin veritabanında birincil anahtar olmasına UserNameneden UserNameolur. Yalnızca UserIdmülk, Keyöznitelikle işaretlenmelidir . Bu çözüm, size yanlış bir veritabanı tasarımı verirken, programlama tarafında size 'doğru' davranışı verecektir.
Alex Jorgenson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.