Acelerar as inserções do LINQ

Eu tenho um arquivo CSV e tenho que inseri-lo em um banco de dados do SQL Server. Existe uma maneira de acelerar as inserções do LINQ?

Eu criei um método de repositório simples para salvar um registro:

    public void SaveOffer(Offer offer)
    {
        Offer dbOffer = this.db.Offers.SingleOrDefault (
             o => o.offer_id == offer.offer_id);

        // add new offer
        if (dbOffer == null)
        {
            this.db.Offers.InsertOnSubmit(offer);
        }
        //update existing offer
        else
        {
            dbOffer = offer;
        }

        this.db.SubmitChanges();
    }

Mas, usando este método, o programa é muito mais lento do que inserir os dados usando inserções do ADO.net SQL (novo SqlConnection, novo SqlCommand para seleção se existir, novo SqlCommand para atualização / inserção).

Em linhas de 100k csv, leva cerca de uma hora contra 1 minuto ou mais para o caminho do ADO.net. Para as linhas 2M csv, o ADO.net demorou cerca de 20 minutos. LINQ adicionou cerca de 30k dessas linhas de 2M em 25 minutos. Meu banco de dados tem 3 tabelas, vinculadas no dbml, mas as outras duas tabelas estão vazias. Os testes foram feitos com todas as mesas vazias.

P.S. Eu tentei usar SqlBulkCopy, mas eu preciso fazer algumas transformações na oferta antes de inseri-lo no banco de dados, e acho que derrota o propósito de SqlBulkCopy.

Atualizações / Edições: Após 18 horas, a versão LINQ adicionou apenas ~ 200 mil linhas.

Eu testei a importação apenas com inserções LINQ também, e também é muito lento em comparação com o ADO.net. Eu não vi uma grande diferença entre apenas insere / submitchanges e seleciona / updates / inserts / submitchanges.

Eu ainda tenho que tentar o envio em lote, conectando manualmente para o banco de dados e consultas compiladas.

questionAnswers(11)

yourAnswerToTheQuestion