Khi bạn sử dụng Entity Framework, bên trong nó sử dụng OUTPUT
kỹ 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 OUTPUT
giá trị đơn giản là vì EF cũng sử dụng kỹ thuật này để lấy hàng rowversion
mớ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 Timestamp
thuộ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 rowversion
hà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, Timetsamp
bạn không thể sử dụng một OUTPUT
mệnh đề.
Đó là bởi vì nếu có một kích hoạt trên bàn, bất kỳ Timestamp
bạ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 SELECT
là bạn không thể ĐẦU RA một rowversion
biế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 UPDATE
trên bảng với một kích hoạt, bạn không thể sử dụng một OUTPUT
mệnh đề. Thử làm UPDATE
với một OUTPUT
không được hỗ trợ và sẽ báo lỗi:
Cách duy nhất để làm điều đó là với một SELECT
tuyê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 ().