Skip to content

Commit b2311fe

Browse files
committed
Prefetch extension for QueryResult
- extension itself - IMaterializingReader extended with Session property - access to reader for internal use
1 parent 7bc9865 commit b2311fe

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

Orm/Xtensive.Orm/Orm/Linq/Materialization/MaterializingReader.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace Xtensive.Orm.Linq.Materialization
1313
{
1414
internal interface IMaterializingReader<out TItem>
1515
{
16+
Session Session { get; }
1617
IEnumerator<TItem> AsEnumerator();
1718
IAsyncEnumerator<TItem> AsAsyncEnumerator();
1819
}
@@ -25,6 +26,8 @@ internal class MaterializingReader<TItem>: IMaterializingReader<TItem>, IEnumera
2526
private readonly IItemMaterializer<TItem> itemMaterializer;
2627
private readonly Queue<Action> materializationQueue;
2728

29+
public Session Session => context.Session;
30+
2831
public IEnumerator<TItem> AsEnumerator()
2932
{
3033
recordSetReader.Reset();

Orm/Xtensive.Orm/Orm/PrefetchExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ public static PrefetchQuery<TElement> Prefetch<TElement, TFieldValue>(
5252
return new PrefetchQuery<TElement>(source.Session, source).RegisterPath(expression);
5353
}
5454

55+
/// <summary>
56+
/// Registers fields specified by <paramref name="expression"/> for prefetch.
57+
/// </summary>
58+
/// <typeparam name="TElement">The type of the element of the source sequence.</typeparam>
59+
/// <typeparam name="TFieldValue">The type of the field's value to be prefetched.</typeparam>
60+
/// <param name="source">The source query.</param>
61+
/// <param name="expression">The expression specifying a field to be prefetched.</param>
62+
/// <returns>An <see cref="IEnumerable{TElement}"/> of source items.</returns>
63+
public static PrefetchQuery<TElement> Prefetch<TElement, TFieldValue>(
64+
this QueryResult<TElement> source,
65+
Expression<Func<TElement, TFieldValue>> expression)
66+
{
67+
var session = source.Reader.Session;
68+
if (session != null) {
69+
return new PrefetchQuery<TElement>(session, source).RegisterPath(expression);
70+
}
71+
return new PrefetchQuery<TElement>(Session.Demand(), source).RegisterPath(expression);
72+
}
73+
74+
75+
5576
/// <summary>
5677
/// Registers fields specified by <paramref name="expression"/> for prefetch.
5778
/// </summary>

Orm/Xtensive.Orm/Orm/QueryResult.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2020 Xtensive LLC.
1+
// Copyright (C) 2020-2021 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44

@@ -19,6 +19,8 @@ private class EnumerableReader : IMaterializingReader<TItem>
1919
{
2020
private readonly IEnumerable<TItem> items;
2121

22+
public Session Session => null;
23+
2224
public IEnumerator<TItem> AsEnumerator() => items.GetEnumerator();
2325

2426
public IAsyncEnumerator<TItem> AsAsyncEnumerator() => throw new System.NotSupportedException();
@@ -29,17 +31,20 @@ public EnumerableReader(IEnumerable<TItem> items)
2931
}
3032
}
3133

32-
private readonly IMaterializingReader<TItem> reader;
3334
private readonly StateLifetimeToken lifetimeToken;
3435

36+
37+
// DO NOT ENUMERATE this reader anywhere outside this class
38+
internal IMaterializingReader<TItem> Reader { get; }
39+
3540
/// <inheritdoc/>
3641
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
3742

3843
/// <inheritdoc/>
3944
public IEnumerator<TItem> GetEnumerator()
4045
{
4146
EnsureResultsAlive();
42-
return reader.AsEnumerator();
47+
return Reader.AsEnumerator();
4348
}
4449

4550
/// <summary>
@@ -48,7 +53,7 @@ public IEnumerator<TItem> GetEnumerator()
4853
public async IAsyncEnumerable<TItem> AsAsyncEnumerable()
4954
{
5055
EnsureResultsAlive();
51-
var enumerator = reader.AsAsyncEnumerator();
56+
var enumerator = Reader.AsAsyncEnumerator();
5257
while (await enumerator.MoveNextAsync().ConfigureAwait(false)) {
5358
yield return enumerator.Current;
5459
}
@@ -63,13 +68,13 @@ private void EnsureResultsAlive()
6368

6469
internal QueryResult(IMaterializingReader<TItem> reader, StateLifetimeToken lifetimeToken)
6570
{
66-
this.reader = reader;
71+
this.Reader = reader;
6772
this.lifetimeToken = lifetimeToken;
6873
}
6974

7075
internal QueryResult(IEnumerable<TItem> items)
7176
{
72-
reader = new EnumerableReader(items);
77+
Reader = new EnumerableReader(items);
7378
this.lifetimeToken = default;
7479
}
7580
}

0 commit comments

Comments
 (0)