Skip to content

Commit 74f8400

Browse files
authored
Add additional IQueryable extension methods to ResolveConnectionContextExtensions (#177)
1 parent bac5ae2 commit 74f8400

File tree

4 files changed

+79
-32
lines changed

4 files changed

+79
-32
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,31 @@ Convert a connection item cursor to the `int` index of the item in the set.
213213
#### `ConnectionUtils.OffsetToCursor(int offset)`
214214

215215
Convert an index offset to a connection cursor.
216+
217+
#### `ResolveConnectionContextExtensions.ToConnection<TSource>(this IResolveConnectionContext context, IQueryable<TSource> items)`
218+
219+
Creates a connection from an IQueryable.
220+
221+
```csharp
222+
public class Droid
223+
{
224+
public string DroidId { get; set; }
225+
public string Name { get; set; }
226+
public IQueryable<Droid> Friends { get; set; }
227+
}
228+
229+
public class DroidType : ObjectGraphType<Droid>
230+
{
231+
public DroidType()
232+
{
233+
Name = "Droid";
234+
235+
Field<StringGraphType>("name", "The name of the droid.");
236+
237+
Connection<DroidType>()
238+
.Name("friends")
239+
.Resolve(context => context
240+
.ToConnection(c.Source.Friends));
241+
}
242+
}
243+
```

src/GraphQL.Relay.ApiTests/GraphQL.Relay.approved.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ namespace GraphQL.Relay.Types
149149
public int SliceSize { get; }
150150
public int StartIndex { get; }
151151
public int TotalCount { get; }
152+
public GraphQL.Types.Relay.DataObjects.Connection<TSource> ToConnection() { }
152153
}
153154
}
154155
namespace GraphQL.Relay.Utilities
@@ -174,6 +175,7 @@ namespace GraphQL.Relay.Utilities
174175
public static class ResolveConnectionContextExtensions
175176
{
176177
public static GraphQL.Relay.Utilities.EdgeRange EdgesToReturn(this GraphQL.Builders.IResolveConnectionContext context, int edgeCount) { }
178+
public static GraphQL.Types.Relay.DataObjects.Connection<TSource> ToConnection<TSource>(this GraphQL.Builders.IResolveConnectionContext context, System.Linq.IQueryable<TSource> items) { }
177179
public static GraphQL.Types.Relay.DataObjects.Connection<TSource> ToConnection<TSource>(this GraphQL.Builders.IResolveConnectionContext context, System.Collections.Generic.IEnumerable<TSource> items, int? totalCount = default) { }
178180
}
179181
public static class StringExtensions

src/GraphQL.Relay/Types/SliceMetrics.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GraphQL.Builders;
22
using GraphQL.Relay.Utilities;
3+
using GraphQL.Types.Relay.DataObjects;
34

45
namespace GraphQL.Relay.Types
56
{
@@ -106,5 +107,39 @@ int totalCount
106107

107108
StartIndex = edges.StartOffset;
108109
}
110+
111+
/// <summary>
112+
/// Converts current slice to a <see cref="Connection{TSource}"/>
113+
/// </summary>
114+
/// <returns></returns>
115+
public Connection<TSource> ToConnection()
116+
{
117+
var edges = Slice
118+
.Select(
119+
(item, i) =>
120+
new Edge<TSource>
121+
{
122+
Node = item,
123+
Cursor = ConnectionUtils.OffsetToCursor(StartIndex + i)
124+
}
125+
)
126+
.ToList();
127+
128+
var firstEdge = edges.FirstOrDefault();
129+
var lastEdge = edges.LastOrDefault();
130+
131+
return new Connection<TSource>
132+
{
133+
Edges = edges,
134+
TotalCount = TotalCount,
135+
PageInfo = new PageInfo
136+
{
137+
StartCursor = firstEdge?.Cursor,
138+
EndCursor = lastEdge?.Cursor,
139+
HasPreviousPage = HasPrevious,
140+
HasNextPage = HasNext,
141+
}
142+
};
143+
}
109144
}
110145
}

src/GraphQL.Relay/Utilities/ResolveConnectionContextExtensions.cs

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ int edgeCount
3434
);
3535
}
3636

37+
/// <summary>
38+
/// From the connection context, <see cref="IResolveConnectionContext"/>,
39+
/// it creates a <see cref="Connection{TSource}"/> based on the given <see cref="IQueryable{TSource}"/>
40+
/// </summary>
41+
/// <typeparam name="TSource"></typeparam>
42+
/// <param name="context"></param>
43+
/// <param name="items"></param>
44+
/// <returns></returns>
45+
public static Connection<TSource> ToConnection<TSource>(
46+
this IResolveConnectionContext context,
47+
IQueryable<TSource> items
48+
) => SliceMetrics.Create(items, context).ToConnection();
49+
3750
/// <summary>
3851
/// From the connection context, <see cref="IResolveConnectionContext"/>,
3952
/// it creates a <see cref="Connection{TSource}"/> based on the given <see cref="IEnumerable{TSource}"/>
@@ -47,37 +60,6 @@ public static Connection<TSource> ToConnection<TSource>(
4760
this IResolveConnectionContext context,
4861
IEnumerable<TSource> items,
4962
int? totalCount = null
50-
)
51-
{
52-
var metrics = SliceMetrics.Create(
53-
items,
54-
context,
55-
totalCount
56-
);
57-
58-
var edges = metrics.Slice
59-
.Select((item, i) => new Edge<TSource>
60-
{
61-
Node = item,
62-
Cursor = ConnectionUtils.OffsetToCursor(metrics.StartIndex + i)
63-
})
64-
.ToList();
65-
66-
var firstEdge = edges.FirstOrDefault();
67-
var lastEdge = edges.LastOrDefault();
68-
69-
return new Connection<TSource>
70-
{
71-
Edges = edges,
72-
TotalCount = metrics.TotalCount,
73-
PageInfo = new PageInfo
74-
{
75-
StartCursor = firstEdge?.Cursor,
76-
EndCursor = lastEdge?.Cursor,
77-
HasPreviousPage = metrics.HasPrevious,
78-
HasNextPage = metrics.HasNext,
79-
}
80-
};
81-
}
63+
) => SliceMetrics.Create(items, context, totalCount).ToConnection();
8264
}
8365
}

0 commit comments

Comments
 (0)