插入后ConnectionString未初始化!

3
我是一名有用的助手,可以为您翻译文本。

我遇到了一个小问题:每次我的代码执行下面的InsertOrder()例程时,我都会收到这个异常消息:“连接字符串尚未初始化”。

以下是InsertOrder()方法的代码:

  private void InsertOrder()
{
    string insertSQL = "";

    insertSQL += "INSERT INTO Orders (";
    insertSQL += "UserName, DateCreated, LastUpdate, Description, PaymentType, Delivery, Total) ";
    insertSQL += "VALUES (@UserName, @DateCreated, @LastUpdate, @Description, @PaymentType, @Delivery, @Total)";

    SqlCommand cmd0 = new SqlCommand(insertSQL, connection);

    // Adds the parameters
    cmd0.Parameters.AddWithValue("@UserName", Profile.UserName.ToString());
    cmd0.Parameters.AddWithValue("@DateCreated", Profile.Orders.SCart.DateCreated());
    cmd0.Parameters.AddWithValue("@LastUpdate", Profile.Orders.SCart.LastUpdate());
    cmd0.Parameters.AddWithValue("@Description", Profile.Orders.SCart.GetCartDescription());
    cmd0.Parameters.Add("@PaymentType", SqlDbType.Bit).Value = Profile.Orders.SCart.PaymentType;
    cmd0.Parameters.Add("@Delivery", SqlDbType.Bit).Value = Profile.Orders.SCart.Delivery;
    cmd0.Parameters.AddWithValue("@Total", Profile.Orders.SCart.Total);

    try
    {
        using (connection)
        {
            connection.Open();
            cmd0.ExecuteNonQuery();
        }

        string selectSQL = "SELECT OrderID FROM Orders WHERE UserName=@UserName AND DateCreated=@DateCreated";
        SqlCommand cmd1 = new SqlCommand(selectSQL, connection);

        cmd1.Parameters.AddWithValue("@UserName", Profile.UserName);
        cmd1.Parameters.AddWithValue("@DateCreated", Profile.Orders.SCart.DateCreated());
        SqlDataReader reader;

        using (connection)
        {
            connection.Open();
            reader = cmd1.ExecuteReader();
            reader.Read();
            OrderID = (int)reader["OrderID"];
            reader.Close();
        }

        // Store registered customer information for later usage..
        if (!Profile.IsAnonymous)
        {
            string insertSQL2 = "";

            insertSQL2 += "INSERT INTO CategoriesInAnOrder (";
            insertSQL2 += "OrderID, CategoryID, Quantity) VALUES (@OrderID, @CategoryID, @Quantity)";

            foreach (CartItem item in Profile.Orders.SCart.Items)
            {
                SqlCommand cmd2 = new SqlCommand(insertSQL2, connection);
                cmd2.Parameters.AddWithValue("@OrderID", OrderID);
                cmd2.Parameters.AddWithValue("@CategoryID", item.CategoryID);
                cmd2.Parameters.AddWithValue("@Quantity", item.Quantity);
                using (connection)
                {
                    connection.Open();
                    cmd2.ExecuteNonQuery();
                }
            }
        }
    }
    catch (Exception err)
    {
        pnlWizard.Visible = false;
        lblError.Text = err.Message;
    }
}  

可能值得一提的是,我在我的超类中放置了一个SqlConnection对象,因此每个子类(例如包含上述方法的那个)都继承了该属性。

共享的SqlConnection对象设置如下:

    protected SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString);

抱歉我的英语不好...我是意大利人。

你的 web.config 中连接字符串是什么样子的?显然要注释掉用户 ID 和密码 :P - Tim B James
2个回答

3

I think the

using(connection)

可能是您问题的源头。

使用using()将在调用完成时调用Dispose()关闭连接,但您的连接只被实例化一次。

下次使用它时,它将不处于健康状态!

考虑每次创建一个新的连接:

protected SqlConnection connection 
{
    get
    {
        return new SqlConnection
          (System.Web.Configuration.WebConfigurationManager.ConnectionStrings 
          ["DefaultConnectionString"].ConnectionString); 
    }
}

我之前考虑使用一个新的SqlConnection对象,就像你建议的那样,但这完全没有用。每次不使用'using'子句就足以解决问题。非常感谢! - Adriano
已接受。 (抱歉,第一次在StackOverflow :)) - Adriano

3
我怀疑问题在于你正在使用字段的值。这将在一次操作中起作用,但在Dispose()之后,你就已经毁掉了那个连接。
对于这种情况,我使用一个自定义的EnsureOpen()方法,如果它还没有打开,它会返回一个可处理的IDisposable对象; 用法:
using(connection.EnsureOpen())
{
    // use it
}

这样连接就不会过早关闭,需要时保持打开状态。而且它可以在连接已经打开或未打开的情况下工作。
如果您想要,我可以稍后分享EnsureOpen。

我认为EnsureOpen可能是一个有用的安全网,但他可以确信在使用()语句完成后它已经关闭了! - Steve Morgan
@Steve 但如果已经Dispose()了,你就不能再使用它了。EnsureOpen并不会Dispose连接,它只是关闭连接。 - Marc Gravell
我很想看看这个自定义方法!我还是一个 .Net 初学者,所以我想学到更多。 - Adriano
@Marc,啊,我明白了。我猜它返回一个包装器,Dispose()方法调用底层连接的Close()方法? - Steve Morgan
@Steve 正确;@Adriano 将在几个小时内在此发布 - 目前正在使用移动设备。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接