【问题标题】:Save list to database将列表保存到数据库
【发布时间】:2012-09-07 17:18:49
【问题描述】:

这是我目前所拥有的:

Veza.Open();
SqlCommand zadnjaN = new SqlCommand("SELECT TOP 1 id_n FROM Narudzba ORDER BY id_n DESC", Veza);
var id_zn = zadnjaN.ExecuteScalar(); //get 1 value for id_zn (last one entered)
List<int> proizvodi = new List<int>();
proizvodi = (List<int>)Session["kosarica"];
SqlCommand kupnja1 = new SqlCommand("INSERT INTO NarudzbaItemi ([narudzbaID], [proizvodID]) VALUES (@id_zn, @pro)", Veza);
for (int i = 0; i < proizvodi.Count; i++)
{
  kupnja1.Parameters.AddWithValue("pro", proizvodi[i]); //also tried @pro
  kupnja1.Parameters.AddWithValue("id_zn", id_zn); //@id_zn
  kupnja1.ExecuteNonQuery();
}
Veza.Close();

我收到一条消息说变量名@pro 已经被声明。 关键是,我需要在 proizvodID 列中插入一个 int 项目列表,但是我在该列中插入一个值多次我需要在 narudzbaID 列中插入一个不变的值,我从另一个表中获得最后增加的价值。所有 3 列都是 int,Session 是 List int。使用asp.net、c#、sql server 2008。

【问题讨论】:

    标签: c# asp.net sql code-behind


    【解决方案1】:

    您不断在循环中添加参数。在第二次迭代中,@pro 已定义。

    试试这个:

    Veza.Open();
    object id_zn; //get 1 value for id_zn (last one entered)
    using (SqlCommand zadnjaN = new SqlCommand("SELECT TOP 1 id_n FROM Narudzba ORDER BY id_n DESC", Veza))
    {
        id_zn = zadnjaN.ExecuteScalar();
    }
    List<int> proizvodi = (List<int>)Session["kosarica"];
    using (SqlCommand kupnja1 = new SqlCommand("INSERT INTO NarudzbaItemi ([narudzbaID], [proizvodID]) VALUES (@id_zn, @pro)", Veza))
    {
        kupnja1.Parameters.Add("pro"); 
        kupnja1.Parameters.Add("id_zn");
        for (int i = 0; i < proizvodi.Count; i++)
        {
            kupnja1.Parameters["pro"].Value = proizvodi[i]; //also tried @pro
            kupnja1.Parameters["id_zn"].Value = id_zn; //@id_zn
            kupnja1.ExecuteNonQuery();
        }
    }
    Veza.Close();
    

    【讨论】:

    • id_zn 仍然可以使用 addwithValue,不是吗?
    • @RaphaëlAlthaus:是的,但何必呢?一致性更好。
    • 嗯,这是一个观点。另一方面,另一种方式有助于理解哪些变化和哪些没有变化。无论如何,真的很详细......
    • @RaphaëlAlthaus:“发生了什么变化”?一旦编写了代码,这将不会是“更改”。稳定状态的代码(大部分时间)。
    • 我的意思是:当我有两个变量时。 1 有一个在循环中改变的值,另一个对于所有循环的迭代都是相同的:我在循环之外分配不变的 var 的值。
    【解决方案2】:

    这里是如何做到这一点的。但我认为 John Saunders 的方法更好

        for (int i = 0; i < proizvodi.Count; i++)
        {
            //Add this line to clear parameters
            kupnja1.Parameters.Clear();
            kupnja1.Parameters.AddWithValue("pro", proizvodi[i]); //also tried @pro
            kupnja1.Parameters.AddWithValue("id_zn", id_zn); //@id_zn
            kupnja1.ExecuteNonQuery();
        }
    

    【讨论】:

      【解决方案3】:

      这基本上是说你不能一直重复使用相同的命令,这应该可以,将声明移动到循环中:

          Veza.Open();
          SqlCommand zadnjaN = new SqlCommand("SELECT TOP 1 id_n FROM Narudzba ORDER BY id_n DESC", Veza);
          var id_zn = zadnjaN.ExecuteScalar(); //get 1 value for id_zn (last one entered)
          List<int> proizvodi = new List<int>();
          proizvodi = (List<int>)Session["kosarica"];
      
          for (int i = 0; i < proizvodi.Count; i++)
          {
              SqlCommand kupnja1 = new SqlCommand("INSERT INTO NarudzbaItemi ([narudzbaID], [proizvodID]) VALUES (@id_zn, @pro)", Veza);
              kupnja1.Parameters.AddWithValue("pro", proizvodi[i]); //also tried @pro
              kupnja1.Parameters.AddWithValue("id_zn", id_zn); //@id_zn
              kupnja1.ExecuteNonQuery();
          }
          Veza.Close();
      

      【讨论】:

      • -1:如果您要将命令实例化放入循环中,那么您肯定必须在完成后处理命令!
      • @John 还有-1,我会纠正 SQL 注入,但我不会向新程序员讲授如何使用 using,没有必要让程序正常工作,只是一种好的做法。这家伙问的是基础知识,为什么让他不知所措?
      • using 是基本的,尤其是在循环中。请注意您发布的代码:人们会复制它。
      • @John 去测试一下。 C# 可以轻松处理您不在 SqlCommand 上使用 using 的问题。就像您很少在实体连接上使用 using。这不是一个大问题。 SqlConnection 是真正重要的一个。这就像说您应该始终使用StringBuilder 一样教条。如果您仍然怀疑处理 SqlCommand 不是特别重要,请去看看反射器。没有关于它的肯定
      • 在我经常表达的观点中,肯定最好让开发人员养成实现 using 块的习惯,因为他们陷入由于没有这样做而开始出现奇怪错误的情况。无需再讨论这个问题,你并没有被单独挑出来——在你之前我已经对很多人做过了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多