Saya memiliki DB yang sudah ada dengan mana saya ingin membangun aplikasi baru menggunakan EF4.0
Beberapa tabel tidak memiliki kunci utama yang ditentukan sehingga ketika saya membuat Model Data Entitas baru, saya mendapatkan pesan berikut:
The table/view TABLE_NAME does not have a primary key defined
and no valid primary key could be inferred. This table/view has
been excluded. To use the entity, you will need to review your schema,
add the correct keys, and uncomment it.
Jika saya ingin menggunakannya dan memodifikasi data, haruskah saya menambahkan PK ke tabel tersebut, atau apakah ada solusi agar saya tidak harus melakukannya?
.net
entity-framework
Cris
sumber
sumber
Jawaban:
Kesalahan berarti persis apa yang dikatakannya.
Bahkan jika Anda bisa mengatasi ini, percayalah, Anda tidak mau. Jumlah bug membingungkan yang dapat diperkenalkan sangat mengejutkan dan menakutkan, belum lagi fakta bahwa kinerja Anda kemungkinan akan menurun.
Jangan lakukan ini. Perbaiki model data Anda.
EDIT: Saya telah melihat bahwa sejumlah orang menurunkan pertanyaan ini. Saya kira itu baik-baik saja, tetapi perlu diingat bahwa OP bertanya tentang pemetaan tabel tanpa kunci primer, bukan tampilan . Jawabannya masih sama. Bekerja di sekitar kebutuhan EF untuk memiliki PK di atas meja adalah ide yang buruk dari sudut pandang kemudahan pengelolaan, integritas data, dan kinerja.
Beberapa berkomentar bahwa mereka tidak memiliki kemampuan untuk memperbaiki model data yang mendasarinya karena mereka memetakan ke aplikasi pihak ketiga. Itu bukan ide yang baik, karena model dapat berubah dari bawah Anda. Bisa dibilang, dalam hal ini, Anda ingin memetakan ke tampilan, yang, sekali lagi, bukan apa yang diminta OP.
sumber
Saya pikir ini diselesaikan oleh Tillito:
Kerangka Entitas dan Tampilan SQL Server
Saya akan mengutip karyanya di bawah ini:
Kami memiliki masalah yang sama dan ini solusinya:
Untuk memaksa kerangka entitas untuk menggunakan kolom sebagai kunci utama, gunakan ISNULL.
Untuk memaksa kerangka entitas agar tidak menggunakan kolom sebagai kunci utama, gunakan NULLIF.
Cara mudah untuk menerapkan ini adalah dengan membungkus pernyataan pilih tampilan Anda di pilih lain.
Contoh:
dijawab 26 Apr 10 pada 17:00 oleh Tillito
sumber
Bagi mereka yang mencapai pertanyaan ini dan menggunakan Entity Framework Core, Anda tidak perlu lagi menambahkan PK ke tabel mereka atau melakukan solusi apa pun. Sejak EF Core 2.1 kami memiliki fitur baru Jenis Pertanyaan
Jenis pertanyaan harus digunakan untuk:
Jadi di DbContext Anda cukup tambahkan properti tipe berikut,
DbQuery<T>
bukanDbSet<T>
seperti di bawah ini. Dengan asumsi nama tabel Anda adalahMyTable
:sumber
Kunci komposit juga bisa dilakukan dengan Entity Framework Fluent API
sumber
modelBuilder.Entity<T>()
panggilan berantai.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
dengan kunci-kunci oh-begitu-khusus yang tidak alami atau komposit, tetapi dapat diandalkan setelah menjadi unik (biasanya, lagian.)Dalam kasus saya, saya harus memetakan entitas ke tampilan, yang tidak memiliki kunci utama. Selain itu, saya tidak diizinkan untuk mengubah Tampilan ini. Untungnya, Tampilan ini memiliki kolom yang merupakan string unik. Solusi saya adalah menandai kolom ini sebagai kunci utama:
EF curang. Bekerja dengan sempurna, tidak ada yang memperhatikan ... :)
sumber
UserID
kolom jika Anda menggunakan pendekatan Code First ..!Itentity
fungsi. Pada dasarnya, jika saya benar, Itu masih akan membuatUserID
kolom untuk Anda sebagai PK tetapi tidak akan secara otomatis meningkatkanUserID
ketika Anda membuat catatan baru seperti yang akan secara default. Selain itu, Anda masih perlu menyimpan nilai yang berbeda diUserID
.EF tidak memerlukan kunci utama pada basis data. Jika ya, Anda tidak dapat mengikat entitas untuk dilihat.
Anda dapat memodifikasi SSDL (dan CSDL) untuk menentukan bidang unik sebagai kunci utama Anda. Jika Anda tidak memiliki bidang unik, maka saya yakin Anda disemprot. Tetapi Anda benar-benar harus memiliki bidang yang unik (dan PK), jika tidak, Anda akan mengalami masalah nanti.
Erick
sumber
Memiliki kunci identitas yang tidak berguna terkadang tidak ada gunanya. Saya menemukan jika ID tidak digunakan, mengapa menambahkannya? Namun, Entity tidak begitu memaafkan tentang hal itu, jadi menambahkan bidang ID akan lebih baik. Bahkan dalam kasus itu tidak digunakan, itu lebih baik daripada berurusan dengan kesalahan tidak henti Entity tentang kunci identitas yang hilang.
sumber
SOLUSI INI BEKERJA
Anda tidak perlu memetakan secara manual bahkan jika Anda tidak memiliki PK. Anda hanya perlu memberi tahu EF bahwa salah satu kolom Anda adalah indeks dan kolom indeks tidak dapat dibatalkan.
Untuk melakukan ini, Anda dapat menambahkan nomor baris ke tampilan Anda dengan fungsi isNull seperti berikut ini
ISNULL(id, number)
adalah titik kunci di sini karena memberi tahu EF bahwa kolom ini bisa menjadi kunci utamasumber
Jawaban di atas benar jika Anda benar-benar tidak memiliki PK.
Tetapi jika ada satu tetapi tidak ditentukan dengan indeks dalam DB, dan Anda tidak dapat mengubah DB (ya, saya bekerja di dunia Dilbert), Anda dapat memetakan bidang secara manual untuk menjadi kuncinya.
sumber
Ini hanya tambahan untuk jawaban @Erick T. Jika tidak ada kolom tunggal dengan nilai unik, solusinya adalah menggunakan kunci komposit, sebagai berikut:
Sekali lagi, ini hanya solusi. Solusi nyata adalah memperbaiki model data.
sumber
Ini mungkin terlambat untuk menjawab ... namun ...
Jika sebuah tabel tidak memiliki kunci utama maka ada beberapa skenario yang perlu dianalisis untuk membuat EF berfungsi dengan baik. Aturannya adalah: EF akan bekerja dengan tabel / kelas dengan kunci utama. Begitulah cara melacak ...
Katakan, tabel Anda 1. Rekaman unik: keunikan dibuat oleh satu kolom kunci asing: 2. Rekaman unik: keunikan dibuat oleh kombinasi beberapa kolom. 3. Rekaman tidak unik (untuk sebagian besar *).
Untuk skenario # 1 dan # 2 Anda dapat menambahkan baris berikut ke modul DbContext metode OnModelCreating: modelBuilder.Entity (). HasKey (x => new {x.column_a, x.column_b}); // sebanyak kolom yang diperlukan untuk membuat catatan unik.
Untuk skenario # 3 Anda masih dapat menggunakan solusi di atas (# 1 + # 2) setelah Anda mempelajari tabel (* apa yang membuat semua catatan unik). Jika Anda harus menyertakan SEMUA kolom untuk membuat semua catatan unik maka Anda mungkin ingin menambahkan kolom kunci utama ke tabel Anda. Jika tabel ini berasal dari vendor pihak ke-3 daripada mengkloning tabel ini ke database lokal Anda (semalam atau sebanyak yang Anda butuhkan) dengan kolom kunci primer ditambahkan secara sewenang-wenang melalui skrip klon Anda.
sumber
Kerangka Entitas: Menambahkan DataTable tanpa Kunci Utama ke Model Entitas.
sumber
Perbarui ke jawaban @CodeNotFound .
Di EF Core 3.0
DbQuery<T>
sudah usang, alih-alih Anda harus menggunakan jenis entitas Keyless yang seharusnya melakukan hal yang sama. Ini dikonfigurasikan denganHasNoKey()
metode ModelBuilder . Di kelas DbContext Anda, lakukan iniNamun ada beberapa batasan, terutama:
Ini berarti bahwa untuk pertanyaan
Anda tidak dapat mengubah data dengan cara ini - namun Anda dapat membaca. Seseorang dapat membayangkan menggunakan cara lain (misalnya ADO.NET, Dapper) untuk memodifikasi data - ini bisa menjadi solusi dalam kasus di mana Anda jarang perlu melakukan operasi yang tidak dibaca dan masih ingin tetap menggunakan EF Core untuk sebagian besar kasus Anda.
Juga, jika Anda benar-benar membutuhkan / ingin bekerja dengan tabel heap (keyless) - pertimbangkan untuk membuang EF dan menggunakan cara lain untuk berbicara dengan database Anda.
sumber
Dari sudut pandang praktis, setiap meja - bahkan sebuah meja yang didenormalkan seperti meja gudang - harus memiliki kunci utama. Atau, jika gagal, ia setidaknya harus memiliki indeks yang unik dan tidak dapat dibatalkan.
Tanpa semacam kunci unik, rekaman duplikat dapat (dan akan) muncul di tabel, yang sangat bermasalah baik untuk lapisan ORM dan juga untuk pemahaman dasar data. Tabel yang memiliki rekaman duplikat mungkin merupakan gejala desain yang buruk.
Paling tidak, tabel setidaknya harus memiliki kolom identitas. Menambahkan kolom ID pembuatan otomatis membutuhkan waktu sekitar 2 menit di SQL Server dan 5 menit di Oracle. Untuk sedikit usaha ekstra, banyak, banyak masalah akan dihindari.
sumber
Kami juga mengalami masalah ini, dan sementara kami memiliki kolom yang memiliki nol, yang penting adalah kami memiliki kolom dependen yang tidak memiliki nol dan kombinasi dari dua kolom ini unik.
Jadi mengutip tanggapan yang diberikan oleh Pratap Reddy, itu bekerja dengan baik bagi kami.
sumber
Saya sangat senang masalah saya terpecahkan.
Tidak dapat memperbarui EntitySet - karena ia memiliki elemen DefiningQuery dan tidak ada elemen <UpdateFunction>
dan lakukan ini: Lihat di bawah garis itu dan temukan tag. Itu akan memiliki pernyataan pilih ol besar di dalamnya. Hapus tag dan isinya ..
sekarang tanpa mengubah DB TI dapat disisipkan ke tabel yang belum memiliki PK
terima kasih semua dan terima kasih Pharylon
sumber
Di EF Core 5.0, Anda juga dapat mendefinisikannya di level entitas.
Referensi: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-ac-attribute-to-indicate-that-an-entity- tanpa kunci
sumber
Tabel hanya perlu memiliki satu kolom yang tidak memungkinkan nulls
sumber