Saat Anda menggunakan Entity Framework, secara internal menggunakan OUTPUT
teknik untuk mengembalikan nilai ID yang baru saja dimasukkan
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');
SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g
JOIN dbo.TurboEncabulators AS t
ON g.Id = t.TurboEncabulatorID
WHERE @@ROWCOUNT > 0
Hasil output disimpan dalam variabel tabel sementara, bergabung kembali ke tabel, dan mengembalikan nilai baris dari tabel.
Catatan: Saya tidak tahu mengapa EF akan bergabung dengan tabel ephemeral kembali ke meja nyata (dalam keadaan apa keduanya tidak cocok).
Tapi itulah yang dilakukan EF.
Teknik ini ( OUTPUT
) hanya tersedia di SQL Server 2008 atau lebih baru.
Sunting - Alasan untuk bergabung
Alasan Kerangka Entity bergabung kembali ke tabel asli, daripada hanya menggunakan OUTPUT
nilai adalah karena EF juga menggunakan teknik ini untuk mendapatkan rowversion
baris baru yang dimasukkan.
Anda dapat menggunakan konkurensi optimis dalam model kerangka entitas Anda dengan menggunakan Timestamp
atribut: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Saat Anda melakukan ini, Entity Framework akan membutuhkan baris rowversion
yang baru dimasukkan:
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');
SELECT t.[TurboEncabulatorID], t.[RowVersion]
FROM @generated_keys AS g
JOIN dbo.TurboEncabulators AS t
ON g.Id = t.TurboEncabulatorID
WHERE @@ROWCOUNT > 0
Dan untuk mengambil ini, Timetsamp
Anda tidak dapat menggunakan OUTPUT
klausa.
Itu karena jika ada pemicu di atas meja, apa pun yang Timestamp
Anda OUTPUT akan salah:
- Sisipan awal. Stempel waktu: 1
- Output cap waktu klausa OUTPUT: 1
- pemicu memodifikasi baris. Stempel waktu: 2
Stempel waktu yang dikembalikan tidak akan pernah benar jika Anda memiliki pemicu di atas meja. Jadi, Anda harus menggunakan yang terpisah SELECT
.
Dan bahkan jika Anda bersedia untuk menderita versi row salah, alasan lain untuk melakukan terpisah SELECT
adalah bahwa Anda tidak dapat OUTPUT rowversion
menjadi variabel tabel:
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Alasan ketiga untuk melakukannya adalah karena simetri. Saat melakukan UPDATE
di atas meja dengan pemicu, Anda tidak bisa menggunakan OUTPUT
klausa. Mencoba melakukannya UPDATE
dengan OUTPUT
tidak didukung, dan akan memberikan kesalahan:
Satu-satunya cara untuk melakukannya adalah dengan pernyataan tindak lanjut SELECT
:
UPDATE TurboEncabulators
SET StatorSlots = 'Lotus-O deltoid type'
WHERE ((TurboEncabulatorID = 1) AND (RowVersion = 792))
SELECT RowVersion
FROM TurboEncabulators
WHERE @@ROWCOUNT > 0 AND TurboEncabulatorID = 1
INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...)
, atau metode yang lebih lama:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();
Anda bisa mendapatkannya di c # menggunakan ExecuteScalar ().