合并的DataRows未在数据库中更新,但已添加DataRows。为什么?

时间:2015-04-27 10:14:13

标签: c# ms-access datatable oledb

我目前正在尝试阅读大量的excel文件,这些文件存储在一个名为total的数据表中,然后我需要将其保存到访问数据库,它现在可以正常工作,但我担心它会是效率非常低,需要读取的excel文件数量增加。

我找到了这个article,并将其作为我写作功能的基础。

   <?php
$ch = curl_init();
//echo "1";
// set URL and other appropriate options
$ht=curl_setopt($ch, CURLOPT_URL, "http://localhost/vishwas/get.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
$a=curl_exec($ch);

// close cURL resource, and free up system resources
curl_close($ch);

echo $a;
?>

我尝试过使用.Merge()和importrow但是我总是得到一个只包含列名的180kb文件以及它们保存的类型但是当我检查dtmain时它确实保存了我从总计得到的变量,但是当我在itemarray中正常工作。

虽然我已经在询问这个问题了,但是当创建一个文件时,它表示该程序仍在使用它,直到我关闭程序,但据我所知,一切都已关闭,与文件交互,我尝试在所有变量上使用dispose但它仍然存在,这可能是什么问题?

修改

所以我的主要问题是为什么dtMain与total合并时不起作用,但是当每行单独添加它时呢?

编辑2

用户选择要从中导入所有Excel文件的目录

total设置为新的数据表,并填充所有列。

使用

读取目录中找到的所有excel文件
        private void writeAccdb()
    {
        if (File.Exists(saveFileDialog1.FileName))
            File.Delete(saveFileDialog1.FileName);
        OleDbConnection conn;
        OleDbDataAdapter adapter;

        ADOX.Catalog cat = new ADOX.Catalog();
        try
        {
            cat.Create("Provider=Microsoft.ACE.OLEDB." + verFound + ".0;Data Source=" + saveFileDialog1.FileName);
        }
        catch
        {
            return;
        }
        cat = null;
        try
        {
            conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB." + verFound + ".0;Data Source=" + saveFileDialog1.FileName);
            conn.Open();
        }
        catch
        {
            return;
        }
        try
        {
            using (OleDbCommand cmd = new OleDbCommand("CREATE TABLE [Table_1] ([accdb_id] COUNTER PRIMARY KEY, [VALUE] DOUBLE, [TEXT] MEMO);", conn))
            {
                cmd.ExecuteNonQuery();
            }
        }
        catch (Exception ex) { if (ex != null) ex = null;
        }

        adapter = new OleDbDataAdapter("SELECT * FROM [Table_1]", conn);
        OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
        DataTable dtMain = new DataTable();
        adapter.Fill(dtMain);



        //Slow process
        foreach (DataRow row in total.Rows)
        {
            dtMain.Rows.Add(row.ItemArray);
        }
        //Slow process



        adapter.Update(dtMain);
        conn.Close();
    }

然后我尝试将excel文件数据与total合并,但如果结构不正确,则会被忽略。

一旦合并了所有文件,datagridview将获得总数作为数据源。

现在,用户可以选择根据特定标准删除行。

最后是保存过程,所以整体来说它只是一个直接导入,可以选择排除行。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

  

所以我的主要问题是为什么dtMain与总和合并时不起作用,但是当每一行单独添加它时呢?

原因是因为

  1. 当现有DataRow被复制或合并到另一个DataTable时,DataRow的RowState保持不变,
  2. 当我们使用OleDbDataAdapter的.fill方法填充DataTable时,所有行都是使用RowState为&#34; Unchanged&#34;
  3. 创建的

    因此,当您从Excel填充上游DataTable时,行将插入&#34;未更改&#34;,并且当这些行最终合并到&#34; total&#34; DataTable仍然是#34;未改变&#34;。

    示例代码:

    string excelFileSpec = @"C:\Users\Gord\Desktop\Book1.xlsx";
    string excelConnStr =
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + excelFileSpec + ";" +
            "Extended Properties=\"Excel 12.0 Xml;HDR=YES\";";
    using (var excelCon = new OleDbConnection(excelConnStr))
    {
        using (var excelDA = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", excelCon))
        {
            var total = new DataTable();
            excelDA.Fill(total);
            Console.WriteLine("DataAdapter.fill() put {0} row(s) into \"total\":", total.Rows.Count);
            int i = 0;
            foreach (DataRow r in total.Rows)
            {
                Console.WriteLine("    total row[{0}]: RowState is \"{1}\"", i++, r.RowState);
            }
            DataTable dtMain = total.Clone();
            dtMain.Merge(total);
            Console.WriteLine("dtMain.Merge(total); completed. \"dtMain\" contains {0} row(s):", dtMain.Rows.Count);
            i = 0;
            foreach (DataRow r in dtMain.Rows)
            {
                Console.WriteLine("    dtMain row[{0}]: RowState is \"{1}\"", i++, r.RowState);
            }
        }
    }
    

    结果:

    DataAdapter.fill() put 1 row(s) into "total":
        total row[0]: RowState is "Unchanged"
    dtMain.Merge(total); completed. "dtMain" contains 1 row(s):
        dtMain row[0]: RowState is "Unchanged"
    

    因此,当您的其他DataAdapter转到.Update Access数据库时,它会看到&#34; dtMain&#34;中的所有行。是&#34;未改变&#34;它的印象是无所事事。

    另一方面,当你.Add每一行到#34; dtMain&#34;它们被插入到DataTable中作为&#34;添加&#34;所以当.Update发生时,它确实会发送&#34;添加&#34;行到Access数据库。