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

标签 c# asp.net sql 3-tier executereader

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

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;
}

最佳答案

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

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

return result; // here the reader is not valid

一般来说,您不应该将读者返回到业务层。 Reader 应该只在数据访问层使用。应该使用它,然后关闭它和连接。

您应该返回一个在连接关闭后可以工作的对象,例如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;
}

关于C# 阅读器关闭时调用 Read 的尝试无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20469899/

相关文章:

c# - 文本框的 Javascript 注入(inject)攻击预防

javascript - 当后端正在处理某些事情时,如何添加 "Loading icon"并使背景变暗?

c# - 无法打开源 'blah' 的日志。您可能没有写入权限。嗯?

c# - 使用一个 CustomValidator 验证多个错误

mysql - MySQL 查询速度非常慢

c# - 在运行时更改数据集连接字符串

c# - MVC 4 : View is not rendered with the correct data from a List<> in the Model

java.sql.SQLException : You cannot rollback with autocommit set

php - 当我点击 EDIT 链接时,同一页面中的编辑表单不会出现

c# - 连接不同数据库中的两个表