Wenn Sie Entity Framework verwenden, wird die OUTPUT
Technik intern verwendet , um den neu eingefügten ID-Wert zurückzugeben
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
Die Ausgabeergebnisse werden in einer temporären Tabellenvariablen gespeichert, wieder mit der Tabelle verknüpft und geben den Zeilenwert aus der Tabelle zurück.
Hinweis: Ich habe keine Ahnung, warum EF die kurzlebige Tabelle wieder mit der realen Tabelle verbindet (unter welchen Umständen würden die beiden nicht übereinstimmen).
Aber genau das macht EF.
Diese Technik ( OUTPUT
) ist nur unter SQL Server 2008 oder neuer verfügbar.
Bearbeiten - Der Grund für den Join
Der Grund dafür, dass Entity Framework wieder mit der ursprünglichen Tabelle verknüpft wird, anstatt nur die OUTPUT
Werte zu verwenden, liegt darin, dass EF diese Technik auch verwendet, um die rowversion
einer neu eingefügten Zeile abzurufen.
Sie können optimistische Parallelität in Ihren Entity-Framework-Modellen verwenden, indem Sie das folgende Timestamp
Attribut verwenden: 🕗
public class TurboEncabulator
{
public String StatorSlots)
[Timestamp]
public byte[] RowVersion { get; set; }
}
Wenn Sie dies tun, benötigt Entity Framework die rowversion
der neu eingefügten Zeile:
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
Und um diese abzurufen Timetsamp
Sie können nicht eine verwenden OUTPUT
Klausel.
Das liegt daran, dass wenn Sie einen Auslöser auf dem Tisch haben, jeder, den Timestamp
Sie ausgeben, falsch ist:
- Erstes Einfügen. Zeitstempel: 1
- Die OUTPUT-Klausel gibt einen Zeitstempel aus: 1
- Trigger ändert die Zeile. Zeitstempel: 2
Der zurückgegebene Zeitstempel ist niemals korrekt, wenn Sie einen Auslöser auf dem Tisch haben. Sie müssen also eine separate verwenden SELECT
.
Und selbst wenn Sie bereit wären, die falsche Zeilenversion zu erleiden, besteht der andere Grund für die Durchführung einer separaten Version darin, SELECT
dass Sie rowversion
eine Variable nicht in eine Tabellenvariable ausgeben können:
DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');
Der dritte Grund dafür ist die Symmetrie. Wenn eine Durchführung UPDATE
mit einem Trigger auf einem Tisch, man kann nicht eine verwenden OUTPUT
Klausel. Der Versuch, UPDATE
mit einem zu tun, OUTPUT
wird nicht unterstützt und gibt einen Fehler aus:
Der einzige Weg, dies zu tun, ist eine Folgeerklärung 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 (...)
oder ältere Methode:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();
Sie können sie mit ExecuteScalar () in c # abrufen.