Saat Anda menggunakan Entity Framework, secara internal menggunakan OUTPUTteknik 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 OUTPUTnilai adalah karena EF juga menggunakan teknik ini untuk mendapatkan rowversionbaris baru yang dimasukkan.
Anda dapat menggunakan konkurensi optimis dalam model kerangka entitas Anda dengan menggunakan Timestampatribut: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Saat Anda melakukan ini, Entity Framework akan membutuhkan baris rowversionyang 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, TimetsampAnda tidak dapat menggunakan OUTPUTklausa.
Itu karena jika ada pemicu di atas meja, apa pun yang TimestampAnda 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 SELECTadalah bahwa Anda tidak dapat OUTPUT rowversionmenjadi 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 UPDATEdi atas meja dengan pemicu, Anda tidak bisa menggunakan OUTPUTklausa. Mencoba melakukannya UPDATEdengan OUTPUTtidak 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 ().