ConnectionString属性尚未初始化,连接的当前状态已关闭

时间:2018-04-08 14:38:40

标签: c# asp.net sql-server

首先,我要感谢你们所有人。我正在尝试将我的网站上传到我在 localhost 时工作得很好的主机,但是现在,在我上传之后,我收到了这个错误:

  

ConnectionString属性尚未初始化,ExecuteReader需要一个开放且可用的连接。连接的当前状态已关闭。

我尝试使用 localhost 的SQL Server Web主机访问权限并且它有效, 我正在使用具有连接字符串的Class call DB。

SqlConnection cn;
SqlCommand cmd;
DataTable dt;

public SqlDataAdapter sda;
public SqlDataReader sdr;

private void BeRedy(CommandType CT, string DBCall)
{
    try
    {
        cn = new SqlConnection();
        cn.ConnectionString = ConfigurationManager.ConnectionStrings["BooksConnectionString"].ToString();
        cn.Open();

        cmd = new SqlCommand(DBCall);
        cmd.CommandType = CT;
    }
    catch (Exception ex)
    {
        cmd = new SqlCommand();
    }
    finally
    {
        cmd.Connection = cn;
    }
}

public SqlDataReader ReadQuery(string query)
{
    BeRedy(CommandType.Text, query);

    if (cn.State == ConnectionState.Closed)
    {
        cn = new SqlConnection();
        cn.ConnectionString = ConfigurationManager.ConnectionStrings["BooksConnectionString"].ToString();
        cn.Open();

        SqlDataReader dr = cmd.ExecuteReader();
        return dr;
    }
    else
    {
        SqlDataReader dr = cmd.ExecuteReader();
        return dr;
    }
}

public void BindDataList(string query, DataList DTS)
{
    String SqlSelect = query;
    DataTable dt = ReadQueryDt(SqlSelect);
    DTS.DataSource = dt;
    DTS.DataBind();
}   

protected void Page_Load(object sender, EventArgs e)
{
    LoadMostWatchedVideo();
}    

void LoadMostWatchedVideo()
{
    string query = "SELECT TOP (4) * FROM Video ORDER BY watched DESC";
    DataTable dt = db.ReadQueryDt(query);
    DtTopWatched.DataSource = dt;
    DtTopWatched.DataBind();
}

1 个答案:

答案 0 :(得分:0)

代码存在一些严重问题。你坐下来真的想过吗?你需要思考一下你想要完成的事情。

首先,不要将SqlCommand或SqlConnection存储为类中的字段。它们通常应该只是局部变量,应尽快关闭它们。

另一个提示是不使用DataTable。与定义用于表示数据的实际类相比,它们更难以使用。

使用类而不是DataTable时,最好有一个可以自动将SQL查询结果转换为强类型类的库。我们将这些库称为“对象关系映射器”。 Stack Overflow本身使用Dapper。它简单而快速。您可以通过NuGet将其安装到您的项目中。

这是改进此代码的一种方法。请注意我如何检查不可能发生的情况。

// This class will represent a video.
// The names of the properties should match the names of your columns in your database.
// Since I don't know the actual names of your columns, I'm taking a guess.
public class Video
{
    public int Id { get; set; }

    public string Title { get; set; }
}

// Your actual data access should happen in this class.
// This keeps your UI code separated from your database logic
public class SqlServerVideoRepository
{
    readonly string _connectionString;

    public VideoRepository(string connectionString)
    {
        _connectionstring = connectionString;
    }

    public List<Video> LoadMostWatchedVideos()
    {
        using(var connection = new SqlConnection(_connectionString))
        {
            //Query is an extension method in the Dapper namespace
            return connection.Query<Video>("SELECT TOP (4) * FROM Video ORDER BY watched DESC").AsList();
        }
    }
}


//now in your code behind
protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        var videoRepository = new SqlServerVideoRepository(ConfigurationManager.ConnectionStrings["BooksConnectionString"].ConnectionString);
        var videos = videoRepository.LoadMostWatchedVideos();
        DtTopWatched.DataSource = videos;
        DtTopWatched.DataBind();
    }       
}