Perché My SqlBulkCopy non funziona

asp.net c# sqlbulkcopy sql-server-2005

Domanda

Sto usando l'oggetto SqlBulkCopy per scrivere un datatable in una tabella del server sql. Tuttavia, ogni volta che ricontrollo il mio database rimane intatto senza modifiche. UN

Ho provato a fare ricerche su Google per determinare il mio problema, ma non sono in grado di risolverlo.

Il datatable proveniva da un file .xls.

public static DataTable dt = new DataTable();

private void ExportToGrid(String path, String filen)
    {
        int idx = filen.IndexOf(".");
        string tf = filen.Remove(idx, 4);

        OleDbConnection MyConnection = null;
        DataSet DtSet = null;
        OleDbDataAdapter MyCommand = null;
        MyConnection = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0; Data Source='" + path + "';Extended Properties=Excel 8.0;");

        ArrayList TblName = new ArrayList();

        MyConnection.Open();
        DataTable schemaTable = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
        foreach (DataRow row in schemaTable.Rows)
        {
            TblName.Add(row["TABLE_NAME"]);
        }

        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + TblName[0].ToString() + "]", MyConnection);
        DtSet = new System.Data.DataSet();

        MyCommand.Fill(DtSet);
        MyCommand.FillSchema(DtSet, SchemaType.Source);

        DataTable dt = new DataTable();
        dt = DtSet.Tables[0];
        Session["dt"] = dt;
        int x = dt.Rows.Count;
        MyConnection.Close();

        if (dt.Rows.Count > 0)
        {
            theGridView.DataSource = dt;
            theGridView.DataBind();
        }

        if (System.IO.File.Exists(path))
        {
            System.IO.File.Delete(path);
        }

    }

Questa è la mia funzione di scrittore

private void StartImport()
    {
        string servername = server;
        string database = database;
        string tbl = "dbo.LinkDb";

        Stopwatch sw = new Stopwatch();
        sw.Start();
        SqlBulkCopy bulkCopy = new SqlBulkCopy("Data Source=" + servername + ";Initial Catalog=" + database + ";Integrated Security=SSPI", SqlBulkCopyOptions.TableLock);
        bulkCopy.DestinationTableName = tbl;
        bulkCopy.WriteToServer(dt);
        sw.Stop();
        lblResult.Visible = true;
        lblResult.Text = (sw.ElapsedMilliseconds / 1000.00).ToString();
    }

Di seguito sono riportati gli screenshot delle tabelle memorizzate nel mio server sql. Ti assicuro che mi sono attenuto alle regole Case Sensitive.

tabelle

Non è stata lanciata alcuna eccezione e il tempo medio trascorso è 0,018 - 0,020 secondi

Apprezzo qualsiasi aiuto.

Grazie

Risposta accettata

In base al codice che hai pubblicato, stai scrivendo un datatable vuoto nel database. Il tuo metodo "ExportToGrid" riempie dt, un DataTable dichiarato localmente, che perde scope al di fuori del metodo. La tua funzione di scrittura chiama il DataTable statico dt che è un nuovo datatable.

Deve essere statico? sembra come se questo potesse essere dichiarato come

private DataTable dt;

quindi all'interno di "ExportToGrid" invece di dichiarare un altro DataTable basta istanziare il dt già dichiarato piuttosto che dichiararne uno nuovo

dt = new DataTable();

In alternativa, è possibile estrarre DataTable direttamente da GridView durante il metodo di scrittura:

DataTable dt = (DataTable)theGridView.DataSource;
bulkCopy.WriteToServer(dt);

Ciò elimina la necessità di variabili esterne all'ambito del metodo.

Infine dal momento che stai memorizzando i tuoi dati all'interno della sessione (non sono generalmente un sostenitore di memorizzare grandi quantità di dati nelle variabili di sessione ma senza conoscere le specifiche del tuo sito non posso davvero giudicare), potresti usare il seguente:

DataTable dt = (DataTable)Session["dt"];
bulkCopy.WriteToServer(dt);

Risposta popolare

Non vedo nulla di ovvio rispetto al mio utilizzo, tranne per il fatto che mappo esplicitamente le colonne dalla tabella dei dati alla tabella del database.

Using cn As New SqlConnection(DataAccessResource.CONNECTIONSTRING)
    cn.Open()
    Using copy As New SqlBulkCopy(cn)
        copy.BulkCopyTimeout = 300
        copy.ColumnMappings.Add(0, 0)
        copy.ColumnMappings.Add(1, 1)
        copy.ColumnMappings.Add(2, 2)
        copy.ColumnMappings.Add(3, 3)
        copy.DestinationTableName = "Tablename"
        copy.WriteToServer(dataset.datatable)
    End Using
End Using

Stringa di connessione (sql server 2000!)

"data source=DBSERVERNAME;initial catalog=DBNAME;persist security info=True;user id=USERNAME;password=PASSWORD;packet size=4096"

Dubito che la stringa di connessione sia un problema presumendo di averlo usato altrove.

Infine hai controllato i tipi di dati per le colonne nel dataset datatable corrispondenti a quelli nel database. Nella mia esperienza, il caricamento di oledb da Excel non produce sempre risultati che potresti aspettarti, campi di date e colonne con testo misto e numeri che sono problemi perticulari.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow