Dapper.NET
Temp-Tabellen
Suche…
Temp Tabelle, die vorhanden ist, während die Verbindung offen bleibt
Wenn die temporäre Tabelle von selbst erstellt wird, bleibt sie erhalten, während die Verbindung geöffnet ist.
// Widget has WidgetId, Name, and Quantity properties
public async Task PurchaseWidgets(IEnumerable<Widget> widgets)
{
using(var conn = new SqlConnection("{connection string}")) {
await conn.OpenAsync();
await conn.ExecuteAsync("CREATE TABLE #tmpWidget(WidgetId int, Quantity int)");
// populate the temp table
using(var bulkCopy = new SqlBulkCopy(conn)) {
bulkCopy.BulkCopyTimeout = SqlTimeoutSeconds;
bulkCopy.BatchSize = 500;
bulkCopy.DestinationTableName = "#tmpWidget";
bulkCopy.EnableStreaming = true;
using(var dataReader = widgets.ToDataReader())
{
await bulkCopy.WriteToServerAsync(dataReader);
}
}
await conn.ExecuteAsync(@"
update w
set Quantity = w.Quantity - tw.Quantity
from Widgets w
join #tmpWidget tw on w.WidgetId = tw.WidgetId");
}
}
So arbeiten Sie mit temporären Tabellen
Der Punkt bei temporären Tabellen ist, dass sie auf den Umfang der Verbindung beschränkt sind. Dapper öffnet und schließt automatisch eine Verbindung, wenn diese noch nicht geöffnet ist. Das bedeutet, dass eine temporäre Tabelle direkt nach der Erstellung verloren geht, wenn die an Dapper übergebene Verbindung nicht geöffnet wurde.
Das wird nicht funktionieren:
private async Task<IEnumerable<int>> SelectWidgetsError()
{
using (var conn = new SqlConnection(connectionString))
{
await conn.ExecuteAsync(@"CREATE TABLE #tmpWidget(widgetId int);");
// this will throw an error because the #tmpWidget table no longer exists
await conn.ExecuteAsync(@"insert into #tmpWidget(WidgetId) VALUES (1);");
return await conn.QueryAsync<int>(@"SELECT * FROM #tmpWidget;");
}
}
Auf der anderen Seite funktionieren diese beiden Versionen:
private async Task<IEnumerable<int>> SelectWidgets()
{
using (var conn = new SqlConnection(connectionString))
{
// Here, everything is done in one statement, therefore the temp table
// always stays within the scope of the connection
return await conn.QueryAsync<int>(
@"CREATE TABLE #tmpWidget(widgetId int);
insert into #tmpWidget(WidgetId) VALUES (1);
SELECT * FROM #tmpWidget;");
}
}
private async Task<IEnumerable<int>> SelectWidgetsII()
{
using (var conn = new SqlConnection(connectionString))
{
// Here, everything is done in separate statements. To not loose the
// connection scope, we have to explicitly open it
await conn.OpenAsync();
await conn.ExecuteAsync(@"CREATE TABLE #tmpWidget(widgetId int);");
await conn.ExecuteAsync(@"insert into #tmpWidget(WidgetId) VALUES (1);");
return await conn.QueryAsync<int>(@"SELECT * FROM #tmpWidget;");
}
}
Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow