Entity Framework kullandığınızda OUTPUT, yeni eklenen kimlik değerini döndürmek için tekniği dahili olarak kullanır
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
Çıktı sonuçları geçici bir tablo değişkeninde saklanır, tabloya geri eklenir ve satır değerini tablodan döndürür.
Not: EF'in neden geçici tabloyu gerçek tabloya geri birleştireceği hakkında hiçbir fikrim yok (bu koşullar altında ikisi eşleşmeyecektir).
Ama EF bunu yapar.
Bu teknik ( OUTPUT) yalnızca SQL Server 2008 veya daha yenisinde kullanılabilir.
Düzenle - Katılma nedeni
Entity Framework'ün yalnızca OUTPUTdeğerleri kullanmak yerine orijinal tabloyla birleşmesinin nedeni, EF'in rowversionyeni eklenen bir satırı almak için de bu tekniği kullanmasıdır .
Şu özellik özelliğini kullanarakTimestamp varlık çerçevesi modellerinizde iyimser eşzamanlılık kullanabilirsiniz : 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Bunu yaptığınızda, Entity Framework'ün rowversionyeni eklenen satırın olması gerekir:
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
Ve bu almak üzere Timetsampsize edemez bir kullanma OUTPUTşartı.
Çünkü masada bir tetikleyici Timestampvarsa, OUTPUT ürününüz yanlış olur:
- İlk kesici uç. Zaman damgası: 1
- OUTPUT yan tümcesi çıktı zaman damgası: 1
- tetikleyici satırı değiştirir. Zaman damgası: 2
Tabloda bir tetikleyiciniz varsa , döndürülen zaman damgası hiçbir zaman doğru olmaz. Yani gerekir ayrı kullanın SELECT.
Ve yanlış satır döngüsüne maruz kalmaya istekli olsanız bile, ayrı bir SELECTişlem yapmanın diğer nedeni, rowversionbir tablo değişkenine a OUTPUT alamamanızdır :
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Bunu yapmanın üçüncü nedeni simetri için. Bir yaparken UPDATEtetikleyici içeren bir tablo üzerinde, sen olamaz bir kullanma OUTPUTşartı. A UPDATEile yapmayı denemek OUTPUTdesteklenmez ve bir hata verir:
Bunu yapmanın tek yolu bir takip SELECTifadesidir:
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 (...)veya daha eski bir yöntem:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();ExecuteScalar () kullanarak c # içinde alabilirsiniz.