Compartilhar via


E/S de Blob

Observação

A classe SqliteBlob foi adicionada na versão 3.0.

Você pode reduzir o uso de memória ao ler e gravar objetos grandes transmitindo os dados para dentro e para fora do banco de dados. Isso pode ser especialmente útil ao analisar ou transformar os dados.

Comece inserindo uma linha normalmente. Use a zeroblob() função SQL para alocar espaço no banco de dados para manter o objeto grande. A função last_insert_rowid() fornece uma maneira conveniente de obter seu rowid.

var insertCommand = connection.CreateCommand();
insertCommand.CommandText =
@"
    INSERT INTO data(value)
    VALUES (zeroblob($length));

    SELECT last_insert_rowid();
";
insertCommand.Parameters.AddWithValue("$length", inputStream.Length);
var rowid = (long)insertCommand.ExecuteScalar();

Depois de inserir a linha, abra um fluxo para gravar o objeto grande usando SqliteBlob.

using (var writeStream = new SqliteBlob(connection, "data", "value", rowid))
{
    // NB: Although SQLite doesn't support async, other types of streams do
    await inputStream.CopyToAsync(writeStream);
}

Para transmitir o objeto grande para fora do banco de dados, você deve selecionar o rowid ou um de seus aliases, conforme mostrado aqui, além da coluna do objeto grande. Se você não selecionar o rowid, todo o objeto será carregado na memória. O objeto retornado por GetStream() será um SqliteBlob quando feito corretamente.

var selectCommand = connection.CreateCommand();
selectCommand.CommandText =
@"
    SELECT id, value
    FROM data
    LIMIT 1
";
using (var reader = selectCommand.ExecuteReader())
{
    while (reader.Read())
    {
        using (var readStream = reader.GetStream(1))
        {
            await readStream.CopyToAsync(outputStream);
        }
    }
}