一尘不染

C#无效的尝试在关闭阅读器时调用Read

sql

我在用C#语言执行3层项目时,尝试关闭阅读器时发生无效尝试调用Read的错误。我想做的是通过将两个表连接在一起来检索地址数据列,并显示在下拉列表中。这是我的数据访问层:

    public List<Distribution> getDistributionAll()
    {
        List<Distribution> distributionAll = new List<Distribution>();
        string address;
        SqlDataReader dr = FoodBankDB.executeReader("SELECT b.addressLineOne FROM dbo.Beneficiaries b INNER JOIN dbo.Distributions d ON d.beneficiary = b.id");

        while (dr.Read())
        {
            address = dr["addressLineOne"].ToString();
            distributionAll.Add(new Distribution(address));
        }

        return distributionAll;
    }

这是我的FoodBankDB类:

   public class FoodBankDB
{
    public static string connectionString = Properties.Settings.Default.connectionString;
    public static SqlDataReader executeReader(string query)
    {
        SqlDataReader result = null;
        System.Diagnostics.Debug.WriteLine("FoodBankDB executeReader: " + query);
        SqlConnection connection = new SqlConnection(connectionString);
        SqlCommand command = new SqlCommand(query, connection);
        connection.Open();
        result = command.ExecuteReader();
        connection.Close();
        return result;
    }

我将它们分为两个类,以便每当更改连接字符串时,都可以通过更改FoodBankDB类轻松修改整个项目。

这是我的业务逻辑层:

public List<Distribution> getAllScheduledDistribution()
    {
        List<Distribution> allDistribution = new List<Distribution>();
        Distribution distributionDAL = new Distribution();
        allDistribution = distributionDAL.getDistributionAll();
        return allDistribution;
    }

最后但并非最不重要的一点是,我的表示层:

List<Distribution> scheduledList = new List<Distribution>();
scheduledList = packBLL.getAllScheduledDistribution();
ddlScheduleList.DataSource = scheduledList;
ddlScheduleList.DataTextField = "address";
ddlScheduleList.DataValueField = "address";
ddlScheduleList.DataBind();

如果我不拆分数据访问层和连接字符串类,则效果很好。有人知道如何解决此错误吗?

提前致谢。

更新部分

        public static string GetConnectionString()
    {
        return connectionString;
    }

阅读 219

收藏
2021-03-17

共1个答案

一尘不染

它不起作用,因为您在返回阅读器之前先关闭了连接。阅读器仅在连接打开时才起作用:

result = command.ExecuteReader();
connection.Close();

return result; // here the reader is not valid

一般来说,您不应该使读者回到业务层。阅读器应仅在数据访问层中使用。应该先使用它,然后再关闭连接。

您应该返回一个在连接关闭后可以工作的对象,例如一个DataSetDataTable多个DTO的集合。例如:

public List<Distribution> getDistributionAll()
{
    List<Distribution> distributionAll = new List<Distribution>();

    using (var connection = new SqlConnection(FoodBankDB.GetConnectionString())) // get your connection string from the other class here
    {
        SqlCommand command = new SqlCommand("SELECT b.addressLineOne FROM dbo.Beneficiaries b INNER JOIN dbo.Distributions d ON d.beneficiary = b.id", connection);
        connection.Open();
        using (var dr = command.ExecuteReader())
        {
            while (dr.Read())
            {
                string address = dr["addressLineOne"].ToString();

                distributionAll.Add(new Distribution(address));
            }
        }
    }

    return distributionAll;
}
2021-03-17