UPDATE: Saya mendapatkan beberapa upvotes tentang ini akhir-akhir ini, jadi saya pikir saya akan membiarkan orang tahu saran saya berikan di bawah ini bukan yang terbaik. Karena saya awalnya mulai mengoceh tentang melakukan Entity Framework pada database keyless lama, saya menyadari bahwa hal terbaik yang dapat Anda lakukan DENGAN JAUH adalah melakukannya dengan membalikkan kode-terlebih dahulu. Ada beberapa artikel bagus tentang bagaimana melakukan ini. Cukup ikuti mereka, dan kemudian ketika Anda ingin menambahkan kunci untuk itu, gunakan anotasi data untuk "memalsukan" kunci tersebut.
Sebagai contoh, katakanlah saya tahu meja saya Orders
, walaupun tidak memiliki kunci utama, dijamin hanya memiliki satu nomor pesanan per pelanggan. Karena itu adalah dua kolom pertama di atas tabel, saya akan menyiapkan kode kelas pertama agar terlihat seperti ini:
[Key, Column(Order = 0)]
public Int32? OrderNumber { get; set; }
[Key, Column(Order = 1)]
public String Customer { get; set; }
Dengan melakukan ini, Anda pada dasarnya memalsukan EF agar percaya bahwa ada kunci yang dikelompokkan yang terdiri dari OrderNumber dan Pelanggan. Ini akan memungkinkan Anda untuk melakukan sisipan, pembaruan, dll pada tabel tanpa kunci Anda.
Jika Anda tidak terlalu terbiasa melakukan reverse Code First, buka dan temukan tutorial yang bagus tentang Entity Framework Code First. Kemudian cari satu di Reverse Code First (yang melakukan Code First dengan database yang ada). Kemudian kembali saja ke sini dan lihat saran kunci saya lagi. :)
Jawaban asli :
Pertama: seperti yang orang lain katakan, opsi terbaik adalah menambahkan kunci utama ke tabel. Titik. Jika Anda dapat melakukan ini, jangan baca lagi.
Tetapi jika Anda tidak bisa, atau hanya membenci diri sendiri, ada cara untuk melakukannya tanpa kunci utama.
Dalam kasus saya, saya bekerja dengan sistem legacy (awalnya file datar pada AS400 porting ke Access dan kemudian porting ke T-SQL). Jadi saya harus mencari cara. Ini solusi saya. Berikut ini bekerja untuk saya menggunakan Entity Framework 6.0 (yang terbaru di NuGet pada tulisan ini).
Klik kanan pada file .edmx Anda di Solution Explorer. Pilih "Buka Dengan ..." lalu pilih "Editor XML (Teks)". Kami akan mengedit kode yang dibuat secara otomatis di sini.
Cari garis seperti ini:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
Hapus store:Name="table_name"
dari ujung.
Ubah store:Schema="whatever"
keSchema="whatever"
Lihat di bawah garis itu dan temukan <DefiningQuery>
tag. Itu akan memiliki pernyataan pilih ol besar di dalamnya. Hapus tag dan isinya.
Sekarang baris Anda akan terlihat seperti ini:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
Kami memiliki sesuatu yang lain untuk diubah. Buka file Anda dan temukan ini:
<EntityType Name="table_name">
Di dekatnya, Anda mungkin akan melihat beberapa teks yang dikomentari memperingatkan Anda bahwa itu tidak memiliki kunci utama yang diidentifikasi, sehingga kunci itu telah disimpulkan dan definisi adalah tabel / tampilan read-only. Anda dapat meninggalkannya atau menghapusnya. Saya menghapusnya.
Di bawah ini adalah <Key>
tag. Inilah yang akan digunakan oleh Entity Framework untuk melakukan penyisipan / perbarui / hapus. JADI PASTIKAN ANDA MELAKUKAN HAK INI. Properti (atau properti) dalam tag itu perlu menunjukkan baris yang dapat diidentifikasi secara unik. Sebagai contoh, katakanlah saya tahu meja saya orders
, walaupun tidak memiliki kunci utama, dijamin hanya memiliki satu nomor pesanan per pelanggan.
Jadi milikku terlihat seperti:
<EntityType Name="table_name">
<Key>
<PropertyRef Name="order_numbers" />
<PropertyRef Name="customer_name" />
</Key>
Serius, jangan lakukan ini salah. Katakanlah meskipun tidak boleh ada duplikat, entah bagaimana dua baris masuk ke sistem saya dengan nomor pesanan dan nama pelanggan yang sama. Astaga! Itulah yang saya dapatkan karena tidak menggunakan kunci! Jadi saya menggunakan Entity Framework untuk menghapusnya. Karena saya tahu duplikat adalah satu-satunya pesanan yang dimasukkan hari ini, saya melakukan ini:
var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);
Tebak apa? Saya baru saja menghapus duplikat DAN yang asli! Itu karena saya mengatakan kepada Entity Framework bahwa order_number / cutomer_name adalah kunci utama saya. Jadi ketika saya mengatakannya untuk menghapus duplikat Order, apa yang dilakukan di latar belakang adalah sesuatu seperti:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
Dan dengan peringatan itu ... Anda sekarang harus pergi dengan baik!