File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -357,12 +357,18 @@ public void TestQuery()
357357 using ( var stmt = db . PrepareStatement ( "SELECT * from FOO WHERE v < ?" ) )
358358 {
359359 var result = stmt . Query ( 50 ) . Count ( ) ;
360+
361+ // Ensure that enumerating the Query Enumerable doesn't dispose the stmt
362+ Assert . DoesNotThrow ( ( ) => { var x = stmt . IsBusy ; } ) ;
360363 Assert . AreEqual ( result , 50 ) ;
361364 }
362365
363366 using ( var stmt = db . PrepareStatement ( "SELECT * from FOO WHERE v < 50" ) )
364367 {
365368 var result = stmt . Query ( ) . Count ( ) ;
369+
370+ // Ensure that enumerating the Query Enumerable doesn't dispose the stmt
371+ Assert . DoesNotThrow ( ( ) => { var x = stmt . IsBusy ; } ) ;
366372 Assert . AreEqual ( result , 50 ) ;
367373 }
368374 }
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ limitations under the License.
1616*/
1717
1818using System ;
19+ using System . Collections ;
1920using System . Collections . Generic ;
2021using System . Diagnostics . Contracts ;
2122using System . IO ;
@@ -111,7 +112,9 @@ public static IEnumerable<IReadOnlyList<IResultSetValue>> Query(
111112 This . Reset ( ) ;
112113 This . ClearBindings ( ) ;
113114 This . Bind ( values ) ;
114- return This ;
115+
116+ // Prevent the statement from being disposed when the enumerator is disposed
117+ return new NonDisposingEnumerator < IReadOnlyList < IResultSetValue > > ( This ) ;
115118 } ) ;
116119 }
117120
@@ -127,8 +130,52 @@ public static IEnumerable<IReadOnlyList<IResultSetValue>> Query(this IStatement
127130 return new DelegatingEnumerable < IReadOnlyList < IResultSetValue > > ( ( ) =>
128131 {
129132 This . Reset ( ) ;
130- return This ;
133+
134+ // Prevent the statement from being disposed when the enumerator is disposed
135+ return new NonDisposingEnumerator < IReadOnlyList < IResultSetValue > > ( This ) ;
131136 } ) ;
132137 }
133138 }
139+
140+ // An IEnumerator that wraps a delegate, and prevents unintentional disposing of the delegate
141+ internal sealed class NonDisposingEnumerator < T > : IEnumerator < T >
142+ {
143+ private readonly IEnumerator < T > deleg ;
144+
145+ internal NonDisposingEnumerator ( IEnumerator < T > deleg )
146+ {
147+ this . deleg = deleg ;
148+ }
149+
150+ public void Dispose ( )
151+ {
152+ // Intentionally left blank
153+ }
154+
155+ public bool MoveNext ( )
156+ {
157+ return deleg . MoveNext ( ) ;
158+ }
159+
160+ public void Reset ( )
161+ {
162+ deleg . Reset ( ) ;
163+ }
164+
165+ object IEnumerator . Current
166+ {
167+ get
168+ {
169+ return deleg . Current ;
170+ }
171+ }
172+
173+ public T Current
174+ {
175+ get
176+ {
177+ return deleg . Current ;
178+ }
179+ }
180+ }
134181}
You can’t perform that action at this time.
0 commit comments