Khi bạn sử dụng Entity Framework, bên trong nó sử dụng OUTPUTkỹ thuật để trả về giá trị ID mới được chèn
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
Các kết quả đầu ra được lưu trữ trong một biến bảng tạm thời, được nối trở lại bảng và trả về giá trị hàng ra khỏi bảng.
Lưu ý: Tôi không biết tại sao EF lại tham gia bảng phù du trở lại bàn thực (trong trường hợp nào hai người không khớp nhau).
Nhưng đó là những gì EF làm.
Kỹ thuật này ( OUTPUT) chỉ khả dụng trên SQL Server 2008 hoặc mới hơn.
Chỉnh sửa - Lý do tham gia
Lý do mà Entity Framework tham gia trở lại bảng ban đầu, thay vì chỉ sử dụng các OUTPUTgiá trị đơn giản là vì EF cũng sử dụng kỹ thuật này để lấy hàng rowversionmới được chèn.
Bạn có thể sử dụng đồng thời lạc quan trong các mô hình khuôn khổ tổ chức của bạn bằng cách sử dụng các Timestampthuộc tính: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Khi bạn làm điều này, Entity Framework sẽ cần rowversionhàng mới được chèn:
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
Và để lấy lại điều này, Timetsampbạn không thể sử dụng một OUTPUTmệnh đề.
Đó là bởi vì nếu có một kích hoạt trên bàn, bất kỳ Timestampbạn OUTPUT sẽ sai:
- Chèn ban đầu. Dấu thời gian: 1
- Mệnh đề OUTPUT xuất dấu thời gian: 1
- kích hoạt sửa đổi hàng. Dấu thời gian: 2
Dấu thời gian được trả về sẽ không bao giờ chính xác nếu bạn có một kích hoạt trên bàn. Vì vậy, bạn phải sử dụng một riêng biệt SELECT.
Và ngay cả khi bạn sẵn sàng chịu đựng sự đảo ngược không chính xác, lý do khác để thực hiện riêng SELECTlà bạn không thể ĐẦU RA một rowversionbiến trong bảng:
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Lý do thứ ba để làm điều đó là cho sự đối xứng. Khi thực hiện một UPDATEtrên bảng với một kích hoạt, bạn không thể sử dụng một OUTPUTmệnh đề. Thử làm UPDATEvới một OUTPUTkhông được hỗ trợ và sẽ báo lỗi:
Cách duy nhất để làm điều đó là với một SELECTtuyên bố tiếp theo :
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 (...)hoặc phương thức cũ hơn:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();bạn có thể lấy nó trong c # bằng ExecuteScalar ().