Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Gebruik Microsoft. Data.SqlClient-streamingmethoden om grote waarden te verwerken zonder eerst de volledige waarde in het applicatiegeheugen te laden. Streaming is nuttig voor binaire bestanden, grote tekst, XML, JSON en server-naar-server overdracht.
Streaming maakt de waarde niet geschikt voor willekeurige toegang en maakt gelijktijdige bewerkingen op een lezer niet veilig. De verbinding, het commando, de lezer, de bronstroom en het bestemmingsobject moeten actief blijven tot de overdracht is voltooid.
De voorbeelden in dit artikel gaan ervan uit dat een open SqlConnection met de naam connection gericht is op de AdventureWorks-voorbeelddatabase.
De C#-voorbeelden vereisen using Microsoft.Data.SqlClient;. Voorbeelden die gebruik maken van SqlDbType of CommandBehavior, vereisen ook using System.Data;.
Stream data uit een SQL-database
Voer het commando uit met CommandBehavior.SequentialAccess en lees kolommen in volgorde van index. Met sequentiële toegang lees je, nadat je voorbij een kolom bent gegaan, geen eerdere kolom in dezelfde rij.
Gebruik deze SqlDataReader methoden:
| Method | Result | Typische SQL-gegevens |
|---|---|---|
| GetStream | Stream | binary, varbinary, image en gegevens van door de gebruiker gedefinieerde typen (UDT) |
| GetTextReader | TextReader | Karakter- en JSON-gegevens |
| GetXmlReader | XmlReader | xml |
Bel IsDBNull voordat je een stream aanvraagt voor een nullable column. Een streaminggetter gebruikt met een incompatibel SQL-type veroorzaakt een exceptie. Gebruik of gooi de huidige stream weg voordat je een andere kolom leest, de rij verplaatst of naar de volgende resultset gaat.
GetStream wordt niet ondersteund voor versleutelde kolommen.
GetTextReader ondersteunt geen sequentiële toegang tot een versleutelde kolom.
CommandTimeout Dit geldt terwijl Microsoft.Data.SqlClient wacht op netwerkpakketten tijdens uitvoering en lezen. De tijd die je applicatie besteedt aan het verwerken van reeds ontvangen gegevens wordt niet meegeteld. Voor annulering en timeouts, zie Asynchrone programmering.
Binaire gegevens streamen
AdventureWorks slaat bestandsinhoud op in de nullable varbinary(max)Production.Document.Document -kolom. Dit voorbeeld kopieert één waarde naar een bestand met een begrensde buffer:
using var command = new SqlCommand("""
SELECT TOP (1) Document
FROM Production.Document
WHERE Document IS NOT NULL
ORDER BY ModifiedDate DESC;
""", connection);
using SqlDataReader reader = command.ExecuteReader(
CommandBehavior.SequentialAccess);
if (reader.Read())
{
using Stream source = reader.GetStream(0);
using FileStream destination = File.Create("document.bin");
source.CopyTo(destination);
}
Voor tekst gebruik GetTextReader en kopieer naar een TextWriter. Voor XML gebruik GetXmlReader en verwerk XML-nodes zonder de volledige waarde om te zetten in string.
Stream data naar een SQL-database
Stel Value in op een streaming-object en kies een compatibel SQL-type:
| Waardetype | Compatibele parametertypes |
|---|---|
| Stream |
Binary, VarBinary, en het legacy-type Image |
| TextReader |
Char, Text, NText, Xml, de legacy NVarChar- en VarChar-typen, NChar, en Json |
| XmlReader |
Char, Text, NText, Xml, de legacy NVarChar- en VarChar-typen, NChar, en Json |
Stel Size expliciet in.
Size beperkt het over te maken bedrag. Gebruik -1 voor een (max) parameter als je de volledige bron wilt versturen.
Voor begrensde geheugenoverdracht gebruik VarBinary, VarChar of NVarChar met Size = -1, of gebruik Xml of Json. Microsoft.Data.SqlClient buffert de bron in een bytearray of tekenreeks vóór uitvoering voor niet-(max)-teken- en binaire typen en de legacytypen Image, Text en NText.
Stream een parameterwaarde
Dit voorbeeld stuurt een bestand via een varbinary(max) -parameter en geeft het aantal ontvangen bytes terug. Het slaat de waarde niet op:
using FileStream input = File.OpenRead("document.bin");
using var command = new SqlCommand(
"SELECT DATALENGTH(@content);",
connection);
command.Parameters.Add(
new SqlParameter("@content", SqlDbType.VarBinary, -1)
{
Value = input
});
long length = (long)command.ExecuteScalar()!;
Console.WriteLine($"{length} bytes");
Houd het invoerobject open totdat de uitvoering van het commando is voltooid. Geef een annuleringstoken door aan een asynchrone uitvoeringsmethode of roep Cancel aan om annulering van de streamingoperatie aan te vragen. Annuleren gebeurt op basis van best effort. De bewerking kan worden afgerond voordat de annulering van kracht wordt.
Een uitzondering uit de bronstroom of een fout in de lezer verstoort de uitvoering van de opdracht. Probeer het niet opnieuw vanaf hetzelfde object tenzij je de positie kunt vaststellen en de databasebewerking veilig is om te herhalen.
Stream data van de ene SQL-database naar de andere
Dit voorbeeld stuurt een AdventureWorks-documentstroom direct naar een parameter op een andere geopende SqlConnection met de naam destinationConnection. Het voorbeeldcommando geeft de ontvangen lengte weer. Vervang het door het geparametriseerde insert- of updatecommando van de bestemmingsdatabase:
using var readSource = new SqlCommand("""
SELECT TOP (1) Document
FROM Production.Document
WHERE Document IS NOT NULL
ORDER BY ModifiedDate DESC;
""", connection);
using SqlDataReader sourceReader = readSource.ExecuteReader(
CommandBehavior.SequentialAccess);
if (sourceReader.Read())
{
using Stream content = sourceReader.GetStream(0);
using var write = new SqlCommand(
"SELECT DATALENGTH(@content);",
destinationConnection);
write.Parameters.Add(
new SqlParameter("@content", SqlDbType.VarBinary, -1)
{
Value = content
});
Console.WriteLine(write.ExecuteScalar());
}
De bron- en bestemmingscommando's delen geen transactie. Als je applicatie gecoördineerd atomair werk over servers vereist, ontwerp en test dan die transactiegrens apart.