Saya menggunakan Entity Framework 5.0 Code First;
public class Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string EntityId { get; set;}
public int FirstColumn { get; set;}
public int SecondColumn { get; set;}
}
Saya ingin membuat kombinasi antara FirstColumn
dan SecondColumn
unik.
Contoh:
Id FirstColumn SecondColumn
1 1 1 = OK
2 2 1 = OK
3 3 3 = OK
5 3 1 = THIS OK
4 3 3 = GRRRRR! HERE ERROR
Apakah ada cara untuk melakukan itu?
entity-framework
ef-code-first
constraints
multiple-columns
unique-key
Bassam Alugili
sumber
sumber
Saya menemukan tiga cara untuk menyelesaikan masalah.
Indeks unik di EntityFramework Core:
Pendekatan pertama:
Pendekatan kedua untuk membuat Batasan Unik dengan EF Core dengan menggunakan Tombol Alternatif.
Contohnya
Satu kolom:
Beberapa kolom:
EF 6 dan di bawah ini:
Pendekatan pertama:
Pendekatan ini sangat cepat dan bermanfaat tetapi masalah utamanya adalah Kerangka Entity tidak tahu apa-apa tentang perubahan itu!
Pendekatan kedua:
Saya menemukannya di posting ini tetapi saya tidak mencoba sendiri.
Masalah dari pendekatan ini adalah sebagai berikut: Perlu DbMigration jadi apa yang Anda lakukan jika Anda tidak memilikinya?
Pendekatan ketiga:
Saya pikir ini yang terbaik tetapi membutuhkan waktu untuk melakukannya. Saya hanya akan menunjukkan kepada Anda ide di baliknya: Dalam tautan ini http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a Anda dapat menemukan kode untuk anotasi data kunci unik:
Masalah untuk pendekatan ini; Bagaimana saya bisa menggabungkannya? Saya punya ide untuk memperpanjang implementasi Microsoft ini misalnya:
Kemudian di IDatabaseInitializer seperti yang dijelaskan dalam contoh Microsoft Anda dapat menggabungkan kunci sesuai dengan bilangan bulat yang diberikan. Satu hal yang harus diperhatikan: Jika properti unik adalah tipe string maka Anda harus mengatur MaxLength.
sumber
CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})
? (lihat BOL )Jika Anda menggunakan Code-First , Anda dapat menerapkan ekstensi kustom HasUniqueIndexAnnotation
Kemudian gunakan seperti ini:
Yang akan menghasilkan migrasi ini:
Dan akhirnya berakhir di database sebagai:
sumber
this.Property(t => t.Email)
), apa yang berisi kelas? (ie: what isthis
)EntityTypeConfiguration<T>
Anda perlu mendefinisikan kunci komposit.
Dengan anotasi data, tampilannya seperti ini:
Anda juga dapat melakukan ini dengan modelBuilder saat meng-override OnModelCreating dengan menetapkan:
sumber
Jawaban dari niaher yang menyatakan bahwa untuk menggunakan API yang lancar Anda memerlukan ekstensi khusus mungkin sudah benar pada saat penulisan. Anda sekarang dapat (EF core 2.1) menggunakan API yang lancar sebagai berikut:
sumber
Menyelesaikan jawaban chuck untuk menggunakan indeks komposit dengan kunci asing .
Anda perlu mendefinisikan properti yang akan menyimpan nilai kunci asing. Anda kemudian dapat menggunakan properti ini di dalam definisi indeks.
Misalnya, kami memiliki perusahaan dengan karyawan dan hanya kami yang memiliki batasan unik pada (nama, perusahaan) untuk setiap karyawan:
Sekarang pemetaan kelas Karyawan:
Perhatikan bahwa saya juga menggunakan ekstensi @niaher untuk anotasi indeks yang unik.
sumber
Dalam jawaban yang diterima oleh @ chuck, ada komentar yang mengatakan itu tidak akan berfungsi dalam kasus FK.
itu bekerja untuk saya, kasus EF6 .Net4.7.2
sumber
Saya berasumsi bahwa Anda selalu ingin
EntityId
menjadi kunci utama, jadi menggantinya dengan kunci komposit bukan merupakan pilihan (jika saja karena kunci komposit jauh lebih rumit untuk digunakan dan karena sangat tidak masuk akal untuk memiliki kunci primer yang juga memiliki makna dalam logika bisnis).Paling tidak yang harus Anda lakukan adalah membuat kunci unik di kedua bidang dalam database dan secara khusus memeriksa pengecualian pelanggaran kunci unik saat menyimpan perubahan.
Selain itu Anda dapat (harus) memeriksa nilai-nilai unik sebelum menyimpan perubahan. Cara terbaik untuk melakukannya adalah dengan
Any()
kueri, karena meminimalkan jumlah data yang ditransfer:Berhati-hatilah karena pemeriksaan ini saja tidak pernah cukup. Selalu ada beberapa latensi antara cek dan komit aktual, sehingga Anda akan selalu memerlukan penanganan kendala + pengecualian yang unik.
sumber
Baru-baru ini menambahkan kunci komposit dengan keunikan 2 kolom menggunakan pendekatan yang 'direkomendasikan', terima kasih @chuck. Hanya ini yang didekati tampak lebih bersih bagi saya:
sumber