Коли ви використовуєте Entity Framework, він використовує внутрішню OUTPUTтехніку для повернення щойно вставленого значення ID
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
Результати виводу зберігаються у тимчасовій змінній таблиці, приєднуються назад до таблиці і повертають значення рядка з таблиці.
Примітка. Я не маю поняття, чому EF внутрішньо приєднає ефемерну таблицю до реальної таблиці (за яких обставин вони не збігаються).
Але це робить EF.
Ця методика ( OUTPUT) доступна лише на SQL Server 2008 або новіших версіях.
Редагувати - причина приєднання
Причина того, що Entity Framework приєднується до початкової таблиці, а не просто використовувати OUTPUTзначення, полягає в тому, що EF також використовує цю техніку для отримання rowversionщойно вставленого рядка.
Ви можете використовувати оптимістичну сумісність у моделях вашої структури, використовуючи Timestampатрибут: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Коли ви це зробите, Entity Framework потребуватиме rowversionщойно вставлений рядок:
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
І щоб отримати це, Timetsampви не можете використовувати OUTPUTпункт.
Це тому, що якщо на столі є тригер, будь- Timestampякий вивід буде помилятися:
- Початкова вставка. Часова мітка: 1
- Стаття OUTPUT видає часову позначку: 1
- тригер змінює рядок. Часова мітка: 2
Повернута мітка часу ніколи не буде правильною, якщо у вас є тригер на столі. Тому потрібно використовувати окремий SELECT.
І навіть якщо ви були готові зазнати неправильну версію версії, інша причина, щоб виконати окрему, SELECTполягає в тому, що ви не можете вивести А в табличну rowversionзмінну:
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Третя причина цього - симетрія. Виконуючи UPDATEтаблицю за допомогою тригера, ви не можете використовувати OUTPUTпункт. Спроба зробити UPDATEз OUTPUTне підтримується, і це призведе до помилки:
Єдиний спосіб зробити це за допомогою подальшої 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 (...)або старіший метод:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();ви можете отримати його в c # за допомогою ExecuteScalar ().