【问题标题】:List<T> to database and back againList<T> 到数据库并再次返回
【发布时间】:2012-04-02 16:23:06
【问题描述】:

所以我试图将我的列表写入数据库并且我有一些问题。首先,似乎没有任何东西被保存到数据库中,但是到目前为止没有任何错误会导致崩溃,而且我知道这段代码过去曾为我工作过:

    public void saveToDb(int var1, string var2)
    {
        SqlCommand cmd = new SqlCommand("Insert into [table] (col1, col2) VALUES (@param1, @param2)", conn);

        cmd.Parameters.AddWithValue("@param1", var1);
        cmd.Parameters.AddWithValue("@param2", var2);
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
        cmd.Connection.Close();
    }

我有一个三层结构,ui、逻辑和 DAL。首先,它不适用于 DAL 类库中的数据库和 app.config 文件,因此将它们移至主类库,现在它不再抱怨数据库已经存在,而是找到了我的连接字符串。

要将数据发送到这个方法我这样做:

    for (int i = 0; i < myList.Count; i++)
        {
            da.saveToDb(myList.val1, myList.val2);
        }

它没有在代码中给我一个错误,但是当我停止程序时似乎没有任何内容被保存或重置,但我不知道是哪个,但我可以通过在插入之前打印它们来看到变量被正确传递所以我猜Db被重置了?是将我的数据库放入调试文件夹并每次刷新还是什么?

另一件事是我上次这样做时它是一个表单,所以一次总是只有一个插入,现在我的对象列表可以包含从 1 到很多对象的任何地方,通过这种方式我会为我列表中的每个对象打开和关闭数据库连接一次吗?您如何进行批量插入?一直在阅读数据集,但它们似乎都是关于从数据库中读取而不是写入,所以我不确定。我确实使用数据集和适配器从另一个项目中的数据库读取,所以这不应该是一个问题,但我如何将列表批量发送到表中?为了让它更棘手,我不能只转换整个列表,因为 10 个属性 8 个将进入一个表,其余 2 个将进入第二个表,所以我需要循环它们并将相应的属性添加到相应的数据集(或您使用的数据集)。

编辑

我现在做了一些调整,我尝试了两种方法,但都没有奏效,但都没有给出错误,这令人沮丧。

第一种方法:

    public void saveToDb(int val1, string val2)
    {
        SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["[MyConnectionString]"].ConnectionString);
        SqlCommand cmd = new SqlCommand("Insert into [table] (val1, val2) VALUES (@param1, @param2)", conn);

        cmd.Parameters.AddWithValue("@param1", val1);
        cmd.Parameters.AddWithValue("@param2", val2);
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
        cmd.Connection.Close();
    }

第二次我尝试 sqlbulkcopy 一个表:

    public void SaveToDb()
    {

        using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["[MyConnectionString]"].ConnectionString))
        {
            conn.Open();

            using (SqlBulkCopy bulk = new SqlBulkCopy(conn))
            {
                bulk.ColumnMappings.Add("col1", "col1");
                bulk.ColumnMappings.Add("col2", "col1");
                bulk.DestinationTableName = "[table]";

                System.Diagnostics.Debug.Print("Open");
                bulk.WriteToServer(tab);
                foreach (DataRow row in tab.Rows)
                {
                    foreach (var item in row.ItemArray)
                    {
                        System.Diagnostics.Debug.Print(item.ToString());
                    }
                }
                System.Diagnostics.Debug.Print("sending");
            }
            System.Diagnostics.Debug.Print("closing");
        }
    }

我不应该映射它,因为该表包含与具有相同命名(大写/小写)的表完全相同的列,但是主键会增加,所以我映射它所以它应该添加增量自动但没有插入任何内容,打印确实显示了值,但是如果我注释掉映射,我会收到一个错误,说不能分配空值(这是真的,我的表不会取空值)但值不应该是空值,因为它在那里桌子?

【问题讨论】:

  • 我假设您已经查看了数据库以确保这些记录没有被插入,对吧?
  • 不要使用全局连接,而是使用 using-statement 代替 connectionSqlCommand 隐式关闭连接。这也适用于异常情况。您的连接将保持打开状态。
  • 我确实查看了数据库,那里有一些很好的建议,谢谢 Tim。

标签: c# database list ado.net bulkinsert


【解决方案1】:

您似乎忘记了索引。

for (int i = 0; i < myList.Count; i++)
    {
        da.saveToDb(myList[i].val1, myList[i].val2);
    }

【讨论】:

  • 是的,我注意到了,但它在代码中只是在这里输入时错过了它:p。
【解决方案2】:

我认为您缺少连接对象。 var cn = 新的 SqlConnection()。 然后在连接对象上调用 open。

connection.command 将授予对命令对象的访问权限。

【讨论】:

  • 连接对象是全局的,但是根据 Tims 的评论和这个,它改变了。
猜你喜欢
  • 1970-01-01
  • 2010-12-13
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 2014-06-21
  • 2011-02-20
相关资源
最近更新 更多