Untuk beberapa alasan yang saya tidak punya kebebasan untuk berbicara tentang, kami mendefinisikan pandangan pada database Sql Server 2005 kami seperti:
CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
CAST(0 AS BIGINT) AS 'RowNumber',
CAST(0 AS BIGINT) AS 'ProverTicketId',
CAST(0 AS INT) AS 'ReportNumber',
GETDATE() AS 'CompletedDateTime',
CAST(1.1 AS float) AS 'MeterFactor',
CAST(1.1 AS float) AS 'Density',
CAST(1.1 AS float) AS 'FlowRate',
CAST(1.1 AS float) AS 'Average',
CAST(1.1 AS float) AS 'StandardDeviation',
CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1
Idenya adalah bahwa Kerangka Entitas akan membuat entitas berdasarkan kueri ini, yang ia lakukan, tetapi menghasilkannya dengan kesalahan yang menyatakan sebagai berikut:
Peringatan 6002: Tabel / tampilan 'Keystone_Local.dbo.MeterProvingStatisticsPoint' tidak memiliki kunci primer yang ditentukan. Kunci telah disimpulkan dan definisi dibuat sebagai tabel / tampilan hanya-baca.
Dan itu memutuskan bahwa bidang CompletedDateTime akan menjadi kunci utama entitas ini.
Kami menggunakan EdmGen untuk menghasilkan model. Apakah ada cara untuk tidak memiliki kerangka entitas termasuk bidang pandangan ini sebagai kunci utama?
sumber
Saya dapat menyelesaikan ini menggunakan desainer.
Saya tidak perlu mengubah pandangan untuk menggunakan solusi ISNULL, NULLIF, atau COALESCE. Jika Anda memperbarui model Anda dari database, peringatan akan muncul kembali, tetapi akan hilang jika Anda menutup dan membuka kembali VS. Perubahan yang Anda buat pada perancang akan dipertahankan dan tidak terpengaruh oleh penyegaran.
sumber
Setuju dengan @Tillito, namun dalam kebanyakan kasus itu akan mengotori pengoptimal SQL dan tidak akan menggunakan indeks yang benar.
Mungkin terlihat jelas bagi seseorang, tetapi saya menghabiskan waktu berjam-jam untuk memecahkan masalah kinerja menggunakan solusi Tillito. Katakanlah Anda memiliki tabel:
dan pandangan Anda adalah sesuatu seperti ini
Sql optimizer tidak akan menggunakan indeks ix_customer dan itu akan melakukan pemindaian tabel pada indeks primer, tetapi jika bukan:
Kau gunakan
itu akan membuat MS SQL (setidaknya 2008) memasukkan indeks yang tepat ke dalam rencana.
Jika
sumber
Metode ini bekerja dengan baik untuk saya. Saya menggunakan ISNULL () untuk bidang kunci utama, dan COALESCE () jika bidang tidak boleh menjadi kunci utama, tetapi juga harus memiliki nilai yang tidak dapat dibatalkan. Contoh ini menghasilkan bidang ID dengan kunci primer yang tidak dapat dibatalkan. Bidang lainnya bukan kunci, dan memiliki (Tidak Ada) sebagai atribut Nullable mereka.
jika Anda benar-benar tidak memiliki kunci utama, Anda bisa menipu dengan menggunakan ROW_NUMBER untuk menghasilkan kunci-pseudo yang diabaikan oleh kode Anda. Sebagai contoh:
sumber
NEWID() as id
, tapi itu ide yang sama. Dan ada kasus penggunaan yang sah - misalnya jika Anda memiliki tampilan baca-saja. Jelek, EF, jelek.Generator Entity Framework EDM saat ini akan membuat kunci komposit dari semua bidang yang tidak dapat dibatalkan dalam tampilan Anda. Untuk mendapatkan kontrol atas hal ini, Anda perlu memodifikasi tampilan dan kolom tabel yang mendasari pengaturan kolom menjadi nullable ketika Anda tidak ingin mereka menjadi bagian dari kunci utama. Sebaliknya juga benar, seperti yang saya temui, kunci EDM yang dihasilkan menyebabkan masalah duplikasi data, jadi saya harus mendefinisikan kolom nullable sebagai non-nullable untuk memaksa kunci komposit dalam EDM untuk memasukkan kolom itu.
sumber
Context.Entity.ToList()
rekaman duplikat, tetapi jika Anda menjalankan SQL Query yang dihasilkan oleh EF secara langsung (diperoleh dengan LINQPad), tidak ada duplikasi rekaman yang terjadi. Tampaknya ada masalah memetakan catatan database ke objek entitas (POCO) yang dikembalikan, karena PK disimpulkan menggunakan logika yang dijelaskan (kolom yang tidak dapat dibatalkan).Sepertinya itu adalah masalah yang diketahui dengan EdmGen: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/
sumber
Untuk mendapatkan tampilan, saya hanya harus memperlihatkan satu kolom kunci utama. Saya membuat tampilan kedua yang menunjuk ke yang pertama dan menggunakan NULLIF untuk membuat jenis-jenisnya dapat dibatalkan. Ini berhasil bagi saya untuk membuat EF berpikir hanya ada satu kunci utama dalam tampilan.
Tidak yakin apakah ini akan membantu Anda karena saya tidak yakin EF akan menerima entitas tanpa kunci utama.
sumber
Jika Anda tidak ingin dipusingkan dengan apa yang seharusnya menjadi kunci utama, saya sarankan:
ROW_NUMBER
ke dalam pilihan Andasumber
Karena masalah yang disebutkan di atas, saya lebih suka fungsi nilai tabel.
Jika Anda memiliki ini:
buat ini:
Maka Anda cukup mengimpor fungsi daripada tampilan.
sumber