Dukungan streaming SqlClient

Gunakan metode streaming Microsoft.Data.SqlClient untuk memproses nilai besar tanpa terlebih dahulu memuat nilai lengkap ke memori aplikasi. Streaming berguna untuk file biner, teks besar, XML, JSON, dan transfer server-ke-server.

Streaming tidak membuat nilai mendukung seek atau membuat operasi bersamaan pada pembaca menjadi aman. Koneksi, perintah, pembaca, aliran sumber, dan objek tujuan harus tetap hidup hingga transfer selesai.

Contoh dalam artikel ini mengasumsikan bahwa sebuah objek terbuka SqlConnection bernama connection menargetkan database contoh AdventureWorks.

Contoh C# membutuhkan using Microsoft.Data.SqlClient;. Contoh yang menggunakan SqlDbType atau CommandBehavior juga memerlukan using System.Data;.

Alirkan data dari database SQL

Jalankan perintah dengan CommandBehavior.SequentialAccess dan baca kolom dalam urutan ordinal. Dengan akses berurutan, setelah Anda maju melewati sebuah kolom, jangan membaca kolom sebelumnya di baris yang sama.

Gunakan SqlDataReader metode berikut:

Metode Hasil Data SQL umum
GetStream Stream data binary, varbinary, image, dan tipe yang ditentukan pengguna (UDT)
GetTextReader TextReader Data karakter dan JSON
GetXmlReader XmlReader xml

Hubungi IsDBNull sebelum meminta stream untuk kolom nullable. Sebuah streaming getter yang digunakan dengan tipe SQL yang tidak kompatibel melempar pengecualian. Baca atau buang stream saat ini sebelum membaca kolom lain, maju ke baris berikutnya, atau beralih ke hasil berikutnya.

GetStream tidak didukung untuk kolom terenkripsi. GetTextReader tidak mendukung akses berurutan ke kolom terenkripsi.

CommandTimeoutberlaku saat Microsoft. Data.SqlClient menunggu paket jaringan selama eksekusi dan pembacaan. Waktu yang digunakan aplikasi Anda untuk memproses data yang sudah diterima tidak dihitung. Untuk pembatalan dan timeout, lihat Pemrograman asinkron.

Streaming data biner

AdventureWorks menyimpan konten file di kolom nullable varbinary(max)Production.Document.Document. Contoh ini menyalin satu nilai ke file dengan buffer terbatas:

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);
}

Untuk teks, gunakan GetTextReader dan salin ke TextWriter. Untuk XML, gunakan GetXmlReader dan proses node XML tanpa mengubah nilai lengkap menjadi string.

Stream data ke database SQL

Atur Value ke objek streaming dan pilih tipe SQL yang kompatibel:

Jenis nilai Jenis parameter yang kompatibel
Stream Binary, VarBinary, dan tipe warisan Image
TextReader Char, NChar, VarChar, NVarChar, tipe lama Text dan NText, Xml, dan Json
XmlReader Char, NChar, VarChar, NVarChar, tipe lama Text dan NText, Xml, dan Json

Atur Size secara eksplisit. Size membatasi jumlah yang ditransfer. Gunakan -1 untuk parameter bertipe (max) saat Anda ingin mengirim sumber lengkap.

Untuk transfer memori terbatas, gunakan VarBinary, VarChar, atau NVarChar dengan Size = -1, atau gunakan Xml atau Json. Microsoft.Data.SqlClient menyimpan data sumber ke dalam buffer berupa array byte atau string sebelum eksekusi untuk tipe non-(max) karakter dan biner serta tipe legacy Image, Text, dan NText.

Streaming nilai parameter

Contoh ini mengirim file melalui parameter varbinary(max) dan mengembalikan jumlah byte yang diterima. Nilainya tidak disimpan:

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");

Biarkan objek input tetap terbuka sampai eksekusi perintah selesai. Teruskan token pembatalan ke metode eksekusi asinkron atau panggil Cancel untuk meminta pembatalan operasi streaming. Pembatalan diupayakan semaksimal mungkin. Operasi mungkin selesai sebelum pembatalan berlaku.

Pengecualian dari aliran sumber atau pembaca menyebabkan eksekusi perintah gagal. Jangan mencoba ulang dari objek yang sama kecuali Anda dapat menetapkan posisinya dan operasi database aman untuk diulang.

Stream data dari satu database SQL ke database lain

Contoh ini meneruskan aliran dokumen AdventureWorks langsung ke parameter pada SqlConnection lain yang terbuka bernama destinationConnection. Perintah contoh melaporkan panjang data yang diterima. Ganti dengan perintah insert atau update yang diparameterisasi dari database tujuan:

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());
}

Perintah sumber dan tujuan tidak berbagi transaksi. Jika aplikasi Anda membutuhkan kerja atomik yang terkoordinasi di seluruh server, rancang dan uji batas transaksi tersebut secara terpisah.