Ваш лучший вариант - начать транзакцию перед циклом, выполнить каждое утверждение, а не добавлять его в stringbuilder, и зафиксировать после цикла (или каждого n числа записей).
Кроме того, вы должны использовать параметризованные команды, что-то вдоль линий:
SqlCeCommand oCommand = conn.CreateCommand();
oCommand.CommandText = "insert into contacts(name, emails) values(?, ?)";
// I can't remember if the param names need @ or not
oCommand.Parameters.Add("@name", SqlDbType.VarChar);
oCommand.Parameters.Add("@email", SqlDbType.VarChar);
SqlCeTransaction oTrans = conn.BeginTransaction();
try {
foreach (KeyValuePair<string, string> key in list) {
oCommand.Parameters[0].Value = key.Key;
oCommand.Parameters[1].Value = key.Value;
oCommand.ExecuteNonQuery();
}
oTrans.Commit();
} catch (Exception ex) {
oTrans.Rollback();
}
В качестве альтернативы, вы можете использовать SQL Compact Bulk Insert Library из CodePlex. Я считаю, что это использует TableDirect SqlCeCommand поверх SqlCeResultSet, который должен обойти процессор запросов и быть примерно таким же быстрым, как вы можете получить.
Немного вводящий в заблуждение заголовок Я думаю ... Вы хотите, чтобы пакет вставлял список вещей или получал несколько наборов данных из серии избранных? – Martin