Como armazenar massas de dados off-line e, em seguida, atualizá-lo em um banco de dados SQLite em lote?

StackOverflow https://stackoverflow.com/questions/1316292

Pergunta

Atualmente, estou tentando preencher um banco de dados SQLite com dezenas de milhares de dados de texto usando este este método:

SQLiteConnection = new SQLiteConnection(cntnStr);
connection.Open();

foreach(Page p in pages)
{
     using (SQLiteCommand command = new SQLiteCommand(String.Format("Insert Into Pages (ID, Data, Name) Values ({0}, '{1}', '{2}')", id, p.Data, p.Name), connection))
         command.ExecuteNonQuery();
}

No entanto, suspeito que fazer isso cerca de 10 vezes por segundo é provavelmente a abrandar o processo inteiro para baixo. Existe uma maneira que eu possa agrupar os dados na memória e depois adicionar cada 5000 registros ou menos no banco de dados em lote (por isso é mais rápido)?

EDIT: Super-importante: Certifique-se de realizar todos os seus comandos SQL dentro de um DbTransaction - neste caso, um SQLiteTransaction:

SQLiteTransaction trans = connection.BeginTransaction();

// SQL centric code - repeated inserts/changes

trans.Commit(); // adds your changes

Além disso, melhora o desempenho de 1000x.

Foi útil?

Solução

Use uma consulta parametrizada, em vez de construir a consulta usando concatenação:

using (SQLiteConnection = new SQLiteConnection(cntnStr))
{
    connection.Open();

    string query = "Insert Into Pages (ID, Data, Name) Values (?, ?, ?)";
    using (SQLiteCommand command = new SQLiteCommand(query, connection)
    {
        command.Parameters.Add("id", DbType.Int32);
        command.Parameters.Add("data", DbType.String);
        command.Parameters.Add("name", DbType.String);
        foreach(Page p in pages)
        {
             command.Parameters["id"].Value = p.Id;
             command.Parameters["data"].Value = p.Data;
             command.Parameters["name"].Value = p.Name;
             command.ExecuteNonQuery();
        }
    }
}

Este será mais rápido porque o DbCommand é criado apenas uma vez, e a consulta só é analisado uma vez. Além disso, você evitar os riscos de injeção SQL devido à concatenação

BTW, ter um olhar para este artigo por Robert Simpson (autor do provedor SQLite .NET)

Outras dicas

Você terá que lidar com escapando os dados a si mesmo, mas você pode usar uma inserção de lote.

IE:

Insert Into Pages (ID, Data, Name) Values (...),(...),(...),(...)

Você pode carregar a tabela do SQLite DB em um DataTable -Object, em seguida, insira seus registros para o DataTable a objetos e sincronizá-lo de volta a cada 5000 registros para o DB.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top