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

16 c# sql asp.net 3-tier executereader

当我在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;
    }
Run Code Online (Sandbox Code Playgroud)

这是我的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;
    }
Run Code Online (Sandbox Code Playgroud)

我将这些分成两个类,这样每当我的连接字符串被更改时,我都可以通过更改FoodBankDB类来轻松修改整个项目.

这是我的业务逻辑层:

public List<Distribution> getAllScheduledDistribution()
    {
        List<Distribution> allDistribution = new List<Distribution>();
        Distribution distributionDAL = new Distribution();
        allDistribution = distributionDAL.getDistributionAll();
        return allDistribution;
    }
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,我的表达层:

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

如果我没有拆分数据访问层和连接字符串类,它运行良好.有谁知道如何解决这个错误?

提前致谢.

更新部分

        public static string GetConnectionString()
    {
        return connectionString;
    }
Run Code Online (Sandbox Code Playgroud)

Szy*_*mon 27

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

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

return result; // here the reader is not valid
Run Code Online (Sandbox Code Playgroud)

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

您应该返回一个在连接关闭后可以工作的对象,例如一个DataSet或者DataTable一个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;
}
Run Code Online (Sandbox Code Playgroud)


Mou*_*mit 6

上一个是一个很好的例子......但你也可以通过下面的代码实现它,当代码被调用时,它automatically接近一个connection实例datareader.close()...

reader = Sqlcmd.ExecuteReader(CommandBehavior.CloseConnection); 
Run Code Online (Sandbox Code Playgroud)