2015-07-12 189 views
0

我不断收到GetTotalMaterialCost中的错误我已经检查了整件事情。我甚至删除多余的con.Close,但错误仍然会提示。连接未关闭。连接的当前状态已打开。 C#


decimal GetTotalMaterialCost() 
{ 
    decimal total = 0; 
    con.Open(); 
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = con; 
    cmd.CommandText = 
     "SELECT SUM(rm.Quantity * m.SellingPrice) AS TotalMaterialCost FROM Resource_Materials rm " + 
     "JOIN Materials m ON m.MaterialID = rm.MaterialID " + 
     "JOIN ProjectTasks t ON t.TaskID = rm.TaskID " + 
     "WHERE [email protected] HAVING COUNT (*) > 0"; 
    cmd.Parameters.AddWithValue("@TaskID", Request.QueryString["ID"].ToString()); 
    object data = cmd.ExecuteScalar(); 
    if (data == null) 
     total = 0; 
    else 
     total = (decimal)cmd.ExecuteScalar(); 
    con.Close(); 
    return total; 
} 

protected void btnSave_Click(object sender, EventArgs e) 
{ 
    con.Open(); 
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = con; 
    cmd.CommandText = "UPDATE ProjectTasks SET [email protected], [email protected] " + 
     "WHERE [email protected]; " + 
     "SELECT TOP 1 TaskID FROM ProjectTasks ORDER BY TaskID DESC;"; 
    cmd.Parameters.AddWithValue("@Name", txtName.Text); 
    cmd.Parameters.AddWithValue("@Description", txtDescription.Text); 
    cmd.Parameters.AddWithValue("@TaskID", Request.QueryString["ID"].ToString()); 
    cmd.ExecuteNonQuery(); 

    cmd.CommandText = @"UPDATE Resource_Materials SET [email protected] WHERE TaskID=0; " + 
         "UPDATE Resource_Equipments SET [email protected] WHERE TaskID=0; " + 
         "UPDATE Resource_Vehicles SET [email protected] WHERE TaskID=0; " + 
         "UPDATE Resource_Contractors SET [email protected] WHERE TaskID=0; " + 
         "UPDATE Projects SET [email protected] WHERE [email protected]"; 
    cmd.Parameters.AddWithValue("@ProjectID", Request.QueryString["ID"].ToString()); 
    cmd.Parameters.AddWithValue("@ActualCost", GetAmount()); 
    con.Close(); 

    Helper.AddLog("1", "Add", "Assigned Resources to Task"); 
    Response.Redirect("~/Projects/Default.aspx"); 
} 

Here is the link for my whole code as reference


的所述误差是在线路679

回答

3

这通常Happe的ns,因为您使用全局连接对象,并且代码中的某处连接未正确关闭。例如,在你的代码中某处触发了一个异常,并且在这种情况下忘记关闭连接。

分辨率始终相同。
请勿保留全局连接对象。
在需要时创建它,并用适当的语法将其销毁。

There is connection pooling infrastructure in ADO.NET为了在create/open/use/close方案中提供更好的性能而设计。

decimal GetTotalMaterialCost() 
{ 
    decimal total = 0; 
    string query = @"SELECT SUM(rm.Quantity * m.SellingPrice) AS TotalMaterialCost 
        FROM Resource_Materials rm 
        JOIN Materials m ON m.MaterialID = rm.MaterialID 
        JOIN ProjectTasks t ON t.TaskID = rm.TaskID 
        WHERE [email protected] HAVING COUNT (*) > 0"; 

    using(SqlConnection con = new SqlConnection(....constringhere...) 
    using(SqlCommand cmd = new SqlCommand(query, con)) 
    { 
     con.Open(); 
     ..... 
    } 
    return total; 
} 

这样的连接对象是本地和using statement确保关闭并设置在右括号,即使你打了某种异常。

当然,这种模式应该适用于您尝试访问数据库的每一点,并且全局连接对象应该被删除。唯一可以保持全局的是连接字符串,也为此有一个更好的地方来存储它(IE.App.config ConnectionString部分)

说这是一种可能性,你有一个错误引起的通过AddWithValue使用。此方法定义参数的DataType,查看传递的值。看起来你的TaskID字段是一个整数,但你使用AddWithValue准备一个参数并传递一个字符串。所以查询将使用具有错误数据类型的参数。 我建议使用

cmd.Parameters.Add("@TaskID", SqlDbType.Int).Value = 
     Convert.ToInt32(Request.QueryString["ID"].ToString())); 

最后,只给一个粗略地看一眼你的代码,我建议改变你的Page_Load调用的方法接受一个连接对象在Page_Load事件中直接打开

if (!IsPostBack) 
{ 
    using(SqlConnection con = new SqlConnection(....constringhere...) 
    { 
     GetProjectMaterials(con); 
     GetProjectEquipments(con); 
     GetProjectVehicle(con); 
     GetProjectContractors(con); 
     GetTasks(con,resourceID); 
     GetMaterials(con); 
     GetEquipments(con); 
     GetVehicles(con); 
     GetLContractors(con); 
    } 
} 

当然,您还需要更改调用这些方法来传递连接的其他方法,但如果我没有错,则必须在这些调用方中建立连接。

0

我建议你使用本地变量连接“using”,因为.NET SQL提供程序会为你做连接池,“using”将确保你的连接正确关闭和处置。因此,您的代码将如下所示:

decimal GetTotalMaterialCost() 
    { 
     decimal total = 0; 
     using (var con = new SqlConnection(/*connection string if not configured via web.config*/)) 
     { 
      con.Open(); 
      using (SqlCommand cmd = new SqlCommand()) 
      { 
       cmd.Connection = con; 
       cmd.CommandText = 
        "SELECT SUM(rm.Quantity * m.SellingPrice) AS TotalMaterialCost FROM Resource_Materials rm " + 
        "JOIN Materials m ON m.MaterialID = rm.MaterialID " + 
        "JOIN ProjectTasks t ON t.TaskID = rm.TaskID " + 
        "WHERE [email protected] HAVING COUNT (*) > 0"; 
       cmd.Parameters.AddWithValue("@TaskID", Request.QueryString["ID"].ToString()); 
       object data = cmd.ExecuteScalar(); 
       if (data == null) 
        total = 0; 
       else 
        total = (decimal)cmd.ExecuteScalar(); 
      } 
     } 
     return total; 
    } 
0

您打电话cmd.ExecuteScalar()而不重置它。设置total变量的行应为total = (decimal) data;。毕竟,你已经有了答案,为什么不直接使用它而不是重新执行代码呢?

相关问题