关于数据库连接
可能有些人出现过"There is already an open DataReader associated with this Connection which must be closed first.”的错误,这样的错误一般来说是前面使用了一个DataReader对象,该对象还没关闭,现在又使用同一个数据库连接,又创建了一个DataReader对象而导致的。
其实我想说的是,DataAdapter的fill()方法里面也会定义一个DataReader对象的,所以,如果前面试用的DataReader对象还没关闭,在同一个数据库连接中使用DataAdapter的fill()方法的话,也会出现以上的错误,通过Reflector查看DataAdapter的fill()方法,发现里面会调用以下方法:
private int FillInternal(DataSet dataset, DataTable[] datatables, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior) { bool flag = command.Connection == null; try { IDbConnection connection = GetConnection3(this, command, "Fill"); ConnectionState open = ConnectionState.Open; if (MissingSchemaAction.AddWithKey == base.MissingSchemaAction) { behavior |= CommandBehavior.KeyInfo; } try { QuietOpen(connection, out open); behavior |= CommandBehavior.SequentialAccess; using (IDataReader reader = null) { reader = command.ExecuteReader(behavior); if (datatables != null) { return this.Fill(datatables, reader, startRecord, maxRecords); } return this.Fill(dataset, srcTable, reader, startRecord, maxRecords); } } finally { QuietClose(connection, open); } } finally { if (flag) { command.Transaction = null; command.Connection = null; } } return 0; }
会看到,里面也定义了一个DataReader对象,所以,在使用完DataReader对象的时候,最好紧跟着就释放掉,免得一直占用资源。