22// This code is distributed under MIT license terms.
33// See the License.txt file in the project root for more information.
44
5+ using System ;
56using System . Collections ;
67using System . Collections . Generic ;
78using Xtensive . Orm . Linq . Materialization ;
@@ -29,32 +30,47 @@ public EnumerableReader(IEnumerable<TItem> items)
2930 }
3031
3132 private readonly IMaterializingReader < TItem > reader ;
33+ private readonly StateLifetimeToken lifetimeToken ;
3234
3335 /// <inheritdoc/>
3436 IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
3537
3638 /// <inheritdoc/>
37- public IEnumerator < TItem > GetEnumerator ( ) => reader . AsEnumerator ( ) ;
39+ public IEnumerator < TItem > GetEnumerator ( )
40+ {
41+ EnsureResultsAlive ( ) ;
42+ return reader . AsEnumerator ( ) ;
43+ }
3844
3945 /// <summary>
4046 /// Transforms <see cref="QueryResult{TItem}"/> to an <see cref="IAsyncEnumerable{T}"/> sequence.
4147 /// </summary>
4248 public async IAsyncEnumerable < TItem > AsAsyncEnumerable ( )
4349 {
50+ EnsureResultsAlive ( ) ;
4451 var enumerator = reader . AsAsyncEnumerator ( ) ;
4552 while ( await enumerator . MoveNextAsync ( ) . ConfigureAwait ( false ) ) {
4653 yield return enumerator . Current ;
4754 }
4855 }
4956
50- internal QueryResult ( IMaterializingReader < TItem > reader )
57+ private void EnsureResultsAlive ( )
58+ {
59+ if ( lifetimeToken != null && ! lifetimeToken . IsActive ) {
60+ throw new InvalidOperationException ( Strings . ExThisInstanceIsExpiredDueToTransactionBoundaries ) ;
61+ }
62+ }
63+
64+ internal QueryResult ( IMaterializingReader < TItem > reader , StateLifetimeToken lifetimeToken )
5165 {
5266 this . reader = reader ;
67+ this . lifetimeToken = lifetimeToken ;
5368 }
5469
5570 internal QueryResult ( IEnumerable < TItem > items )
5671 {
5772 reader = new EnumerableReader ( items ) ;
73+ this . lifetimeToken = default ;
5874 }
5975 }
6076}
0 commit comments