C#关闭阅读器时无效尝试调用Read
当我在C#语言中进行3层项目时,我无法尝试在读取器关闭时调用Read错误。 我想要做的是通过将两个表连接在一起并在下拉列表中显示来检索地址数据列。 这是我的数据访问层:
public List getDistributionAll() { List distributionAll = new List(); 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 getAllScheduledDistribution() { List allDistribution = new List(); Distribution distributionDAL = new Distribution(); allDistribution = distributionDAL.getDistributionAll(); return allDistribution; }
最后但并非最不重要的是,我的表示层:
List scheduledList = new List(); 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只能在数据访问层中使用。 它应该被使用然后它和连接应该被关闭。
您应该返回一个在连接关闭后可以工作的对象,例如DataSet
或DataTable
或者DTO的集合。 例如:
public List getDistributionAll() { List distributionAll = new List (); 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; }
上一个是一个很好的例子……但你也可以通过下面的代码完成它,当datareader.close()
方法调用时,它会automatically
关闭connection
实例…
reader = Sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);