Gdy używasz Entity Framework, wewnętrznie korzysta z tej OUTPUTtechniki, aby zwrócić nowo wstawioną wartość identyfikatora
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
Wyniki wyjściowe są przechowywane w tymczasowej zmiennej tabeli, łączone z powrotem do tabeli i zwracają wartość wiersza z tabeli.
Uwaga: Nie mam pojęcia, dlaczego EF miałby wewnętrznie dołączyć efemeryczny stół z powrotem do prawdziwego stołu (w jakich okolicznościach te dwa nie pasują).
Ale tak właśnie działa EF.
Ta technika ( OUTPUT) jest dostępna tylko w SQL Server 2008 lub nowszym.
Edytuj - powód przyłączenia
Powodem, dla którego Entity Framework dołącza z powrotem do oryginalnej tabeli, zamiast po prostu używać OUTPUTwartości, jest to, że EF używa tej techniki również w celu uzyskania rowversionnowo wstawionego wiersza.
Z optymistycznej współbieżności można korzystać w modelach struktury encji, używając Timestampatrybutu: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Po wykonaniu tej czynności Entity Framework będzie potrzebował rowversionnowego wiersza:
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
Aby to odzyskać Timetsamp, nie możesz użyć OUTPUTklauzuli.
To dlatego, że jeśli na stole jest wyzwalacz, każde TimestampWYJŚCIE będzie błędne:
- Wstępna wstawka. Znacznik czasu: 1
- Klauzula OUTPUT generuje znacznik czasu: 1
- wyzwalacz modyfikuje wiersz. Znacznik czasu: 2
Zwrócony znacznik czasu nigdy nie będzie poprawny, jeśli masz wyzwalacz na stole. Więc należy użyć oddzielnego SELECT.
I nawet jeśli byłeś skłonny ponieść niepoprawną konwersję wierszy, innym powodem do wykonania osobnego SELECTjest to, że nie możesz WYKONAĆ rowversionzmiennej zmiennej tabeli:
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Trzecim powodem jest symetria. Podczas wykonywania UPDATEna stole z wyzwalaczem nie można użyć OUTPUTklauzuli. Próba wykonania UPDATEza pomocą OUTPUTnie jest obsługiwana i spowoduje błąd:
Jedynym sposobem, aby to zrobić, jest SELECToświadczenie uzupełniające :
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 (...)lub starsza metoda:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();możesz pobrać w c # za pomocą ExecuteScalar ().