Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Használj Microsoft. Data.SqlClient streaming módszereket nagy értékek feldolgozására anélkül, hogy előbb a teljes értéket betöltenénk az alkalmazásmemóriába. A streamelés hasznos bináris fájlokhoz, nagy szöveghez, XML-hez, JSON-hoz és szerverek közötti átvitelhez.
A streaming nem teszi az értéket pozicionálhatóvá, és nem teszi biztonságossá az egyidejű műveleteket az olvasón. A kapcsolatnak, parancsnak, olvasónak, forrásfolyamnak és célobjektumnak életben kell maradnia az átvitel befejezéséig.
A cikkben szereplő példák feltételezik, hogy egy megnyitott SqlConnection nevű connection az AdventureWorks mintaadatbázisra mutat.
A C#-példák megkövetelik a(z) using Microsoft.Data.SqlClient; használatát. Azok a példák, amelyek SqlDbType-t vagy CommandBehavior-et használnak, szintén megkövetelik a(z) using System.Data;-t.
Adatok streamelése SQL-adatbázisból
A parancsot CommandBehavior.SequentialAccess hajtsd végre, és olvasd el az oszlopokat sorrendben. Szekvenciális hozzáférés esetén, miután túlléptél egy oszlopon, ne olvass egy korábbi oszlopot ugyanabban a sorban.
Használd ezeket SqlDataReader a módszereket:
| Method | Result | Minta SQL-adatok |
|---|---|---|
| GetStream | Stream | binary, varbinary, image és felhasználó által definiált típusú (UDT) adatok |
| GetTextReader | TextReader | Karakter- és JSON adatok |
| GetXmlReader | XmlReader | xml |
Hívd meg a(z) IsDBNull elemet, mielőtt streamet kérnél egy nullable oszlophoz. Egy streaming getter, amit nem kompatibilis SQL típussal használnak, kivételt dob. Fogyasztsd vagy dobd el az aktuális adatfolyamot, mielőtt egy másik oszlopot olvasnál, előrelépnél a sorban, vagy a következő eredményre lépnél.
A titkosított oszlopok nem támogatottak a(z) GetStream esetében.
GetTextReader nem támogatja a titkosított oszlophoz való szekvenciális hozzáférést.
CommandTimeout akkor érvényes, amikor a Microsoft.Data.SqlClient hálózati csomagokra vár a végrehajtás és az olvasás során. Az idő, amit az alkalmazásod a már beérkezett adatok feldolgozására fordít, nem számít. A törlés és időkorlátok esetén lásd: Aszinkron programozás.
Bináris adatok streamelése
Az AdventureWorks a fájltartalmat a nullable varbinary(max)Production.Document.Document oszlopban tárolja. Ez a példa egy értéket másol egy fájlba, korlátos puffert használva:
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);
}
Szöveghez használd GetTextReader és másold át ide: TextWriter XML-hez használd GetXmlReader és dolgozd fel az XML csomópontokat anélkül, hogy a teljes értéket sztringgé konvertálnád.
Adatok továbbítása SQL-adatbázisba
Állítsd a(z) Value értékét streaming objektumra, és válassz kompatibilis SQL-típust:
| Érték típusa | Kompatibilis paramétertípusok |
|---|---|
| Stream |
Binary, VarBinary, és a legacy Image típus |
| TextReader |
Char, NChar, VarChar, NVarChar, az örökölt Text és NText típusok, Xml, és Json |
| XmlReader |
Char, NChar, VarChar, NVarChar, az örökölt Text és NText típusok, Xml, és Json |
Állítsa be Size explicit módon.
Size korlátozza az átvitt összeget. Használja a(z) -1 elemet (max) paraméterként, amikor a teljes forrást szeretné elküldeni.
Korlátos memóriaátvitelhez használjunk VarBinary, VarChar, vagy NVarChar a(z) Size = -1 használatával, vagy Xml, vagy Json. A Microsoft.Data.SqlClient a forrást egy bájttömbbe vagy sztringbe puffereli a végrehajtás előtt a nem (max) karakteres és bináris típusok, valamint a régi Image, Text és NText típusok esetén.
Paraméterérték streamelése
Ez a példa egy fájlt egy varbinary(max) paraméteren keresztül küld, és visszaadja a kapott bájtok számát. Nem tárolja az értéket:
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");
Tartsd nyitva a bemeneti objektumot, amíg a parancs végrehajtása be nem fejeződik. Adj át egy megszakítási tokent egy aszinkron végrehajtási metódusnak, vagy hívd meg a(z) Cancel elemet a streamelési művelet megszakításának kérésére. A lemondás a lehetőségekhez mérten történik. A művelet lehet, hogy a megszakítás hatálybalépése előtt befejeződik.
A forrásfolyam vagy az olvasó kivétele meghiúsítja a parancs végrehajtását. Ne próbáld újra ugyanazzal az objektummal, hacsak nem tudod megállapítani a pozícióját, és az adatbázis-művelet biztonságosan megismételhető.
Adatok továbbítása egyik SQL adatbázisból a másikba
Ez a példa egy AdventureWorks dokumentumfolyamot közvetlenül egy másik, destinationConnection nevű nyitott SqlConnection paraméteréhez továbbít. A mintaparancs a fogadott hosszát jelzi. Cseréld le a céladatbázis paraméterezett beszúrási vagy frissítési parancsára:
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());
}
A forrás- és célparancsok nem ugyanazt a tranzakciót használják. Ha az alkalmazásod koordinált atomi munkát igényel szerverek között, tervezd meg és teszteld ezt a tranzakciós határt külön.