Skip to content
This repository was archived by the owner on Aug 25, 2025. It is now read-only.

Commit 672e85a

Browse files
FIND-13326: Fragment can be set for deep level of field
- Add method AddFragmentFor(field, fragment) to support add fragment to field
1 parent 8bd3631 commit 672e85a

File tree

3 files changed

+76
-90
lines changed

3 files changed

+76
-90
lines changed

APIs/src/EpiServer.ContentGraph/Api/Querying/BaseTypeQueryBuilder.cs

Lines changed: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,7 @@ public virtual BaseTypeQueryBuilder Field(string propertyName)
5656
if (!propertyName.IsNullOrEmpty())
5757
{
5858
string clonedPropName = ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName);
59-
graphObject.SelectItems.Append(
60-
graphObject.SelectItems.Length == 0 ?
61-
$"{clonedPropName}" :
62-
$" {clonedPropName}"
63-
);
59+
AppendItem(clonedPropName);
6460
}
6561

6662
return this;
@@ -72,11 +68,7 @@ public virtual BaseTypeQueryBuilder Field(string propertyName, string alias)
7268
if (!propertyName.IsNullOrEmpty() && !alias.IsNullOrEmpty())
7369
{
7470
string clonedPropName = ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName);
75-
graphObject.SelectItems.Append(
76-
graphObject.SelectItems.Length == 0 ?
77-
$"{alias}:{clonedPropName}" :
78-
$" {alias}:{clonedPropName}"
79-
);
71+
AppendItem($"{alias}:{clonedPropName}");
8072
}
8173
else
8274
{
@@ -97,11 +89,7 @@ public virtual BaseTypeQueryBuilder Field(string propertyName, HighLightOptions
9789
return this;
9890
}
9991
string clonedPropName = ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName);
100-
graphObject.SelectItems.Append(
101-
graphObject.SelectItems.Length == 0 ?
102-
$"{clonedPropName}{highLightOptions.Query}" :
103-
$" {clonedPropName}{highLightOptions.Query}"
104-
);
92+
AppendItem($"{clonedPropName}{highLightOptions.Query}");
10593
}
10694

10795
return this;
@@ -119,17 +107,9 @@ public virtual BaseTypeQueryBuilder Link(ITypeQueryBuilder link)
119107
{
120108
if (!linkQueryBuilder.GetLinkType().IsNullOrEmpty())
121109
{
122-
graphObject.SelectItems.Append(
123-
graphObject.SelectItems.Length == 0 ?
124-
$"_link(type:{linkQueryBuilder.GetLinkType()})" :
125-
$" _link(type:{linkQueryBuilder.GetLinkType()})"
126-
);
110+
AppendItem($"_link(type:{linkQueryBuilder.GetLinkType()})");
127111
}
128-
graphObject.SelectItems.Append(
129-
graphObject.SelectItems.Length == 0 ?
130-
$"{{{linkQuery}}}" :
131-
$" {{{linkQuery}}}"
132-
);
112+
AppendItem($"{{{linkQuery}}}");
133113
}
134114
return this;
135115
}
@@ -152,27 +132,15 @@ public virtual BaseTypeQueryBuilder Link(ITypeQueryBuilder link, string alias)
152132
{
153133
if (string.IsNullOrEmpty(alias))
154134
{
155-
graphObject.SelectItems.Append(
156-
graphObject.SelectItems.Length == 0 ?
157-
$"_link(type:{linkQueryBuilder.GetLinkType()})" :
158-
$" _link(type:{linkQueryBuilder.GetLinkType()})"
159-
);
135+
AppendItem($"_link(type:{linkQueryBuilder.GetLinkType()})");
160136
}
161137
else
162138
{
163-
graphObject.SelectItems.Append(
164-
graphObject.SelectItems.Length == 0 ?
165-
$"{alias}:_link(type:{linkQueryBuilder.GetLinkType()})" :
166-
$" {alias}:_link(type:{linkQueryBuilder.GetLinkType()})"
167-
);
139+
AppendItem($"{alias}:_link(type:{linkQueryBuilder.GetLinkType()})");
168140
}
169141

170142
}
171-
graphObject.SelectItems.Append(
172-
graphObject.SelectItems.Length == 0 ?
173-
$"{{{linkQuery}}}" :
174-
$" {{{linkQuery}}}"
175-
);
143+
AppendItem($"{{{linkQuery}}}");
176144

177145
}
178146
return this;
@@ -184,11 +152,7 @@ public virtual BaseTypeQueryBuilder Children(ITypeQueryBuilder children)
184152
string childrenItems = children.GetQuery()?.Query ?? string.Empty;
185153
if (!childrenItems.IsNullOrEmpty())
186154
{
187-
graphObject.SelectItems.Append(
188-
graphObject.SelectItems.Length == 0 ?
189-
$"_children{{{childrenItems}}}" :
190-
$" _children{{{childrenItems}}}"
191-
);
155+
AppendItem($"_children{{{childrenItems}}}");
192156
}
193157

194158
return this;
@@ -203,13 +167,27 @@ public virtual BaseTypeQueryBuilder AddFragments(params FragmentBuilder[] fragme
203167
return this;
204168
}
205169
protected virtual BaseTypeQueryBuilder AddFragment(FragmentBuilder fragment)
170+
{
171+
AddFragment(null, fragment);
172+
return this;
173+
}
174+
public virtual BaseTypeQueryBuilder AddFragment(string fieldPath, FragmentBuilder fragment)
206175
{
207176
fragment.ValidateNotNullArgument("fragment");
208-
graphObject.SelectItems.Append(
209-
graphObject.SelectItems.Length == 0 ?
210-
$"...{fragment.GetName()}" :
211-
$" ...{fragment.GetName()}"
212-
);
177+
string propName;
178+
if (fieldPath.IsNullOrEmpty())
179+
{
180+
propName = $"...{fragment.GetName()}";
181+
}
182+
else
183+
{
184+
var newPath = $"{fieldPath}.$$${fragment.GetName()}";
185+
//trick: fragment init by $$$ then replace by dots ...
186+
propName = ConvertNestedFieldToString.ConvertNestedFieldForQuery(newPath);
187+
propName = propName.Replace("$", ".");
188+
}
189+
190+
AppendItem(propName);
213191

214192
if (Parent != null)
215193
{
@@ -239,5 +217,13 @@ private IEnumerable<FragmentBuilder> GetAllChildren(FragmentBuilder fragment)
239217
}
240218
}
241219
}
220+
221+
protected virtual void AppendItem(string item)
222+
{
223+
if (!item.IsNullOrEmpty())
224+
{
225+
graphObject.SelectItems.Append(graphObject.SelectItems.Length > 0 ? $" {item}": item);
226+
}
227+
}
242228
}
243229
}

APIs/src/EpiServer.ContentGraph/Api/Querying/FragmentBuilder.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ public override FragmentBuilder AddFragments(params FragmentBuilder[] fragments)
6060
}
6161
return this;
6262
}
63+
public FragmentBuilder AddFragment(string path, FragmentBuilder fragment)
64+
{
65+
if (_childrenFragments.IsNull())
66+
{
67+
_childrenFragments = new List<FragmentBuilder>();
68+
}
69+
base.AddFragment(path, fragment);
70+
_childrenFragments.Add(fragment);
71+
72+
return this;
73+
}
6374
}
6475

6576
public class FragmentBuilder<T> : FragmentBuilder
@@ -112,10 +123,7 @@ private FragmentBuilder Recursive<TSub>(params Recursion[] recursives) where TSu
112123
}
113124

114125
string subTypeName = typeof(TSub).Name;
115-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
116-
$"... on {subTypeName}{{{recursiveNess}}}" :
117-
$" ... on {subTypeName}{{{recursiveNess}}}"
118-
);
126+
AppendItem($"... on {subTypeName}{{{recursiveNess}}}");
119127
return this;
120128
}
121129
private FragmentBuilder<T> Recursive<TSub>(string fieldName, int? depth = null) where TSub : T
@@ -154,10 +162,7 @@ public FragmentBuilder<T> Inline<TSub>(params string[] fields)
154162
propertyBuilder.Append(ConvertNestedFieldToString.ConvertNestedFieldForQuery(field));
155163
}
156164
string subTypeName = typeof(TSub).Name;
157-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
158-
$"... on {subTypeName}{{{propertyBuilder}}}" :
159-
$" ... on {subTypeName}{{{propertyBuilder}}}"
160-
);
165+
AppendItem($"... on {subTypeName}{{{propertyBuilder}}}");
161166
return this;
162167
}
163168
/// <summary>
@@ -179,10 +184,7 @@ public FragmentBuilder<T> Inline<TSub>(params Expression<Func<TSub, object>>[] f
179184
propertyBuilder.Append(ConvertNestedFieldToString.ConvertNestedFieldForQuery(fieldSelector.GetFieldPath()));
180185
}
181186
string subTypeName = typeof(TSub).Name;
182-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
183-
$"... on {subTypeName}{{{propertyBuilder}}}" :
184-
$" ... on {subTypeName}{{{propertyBuilder}}}"
185-
);
187+
AppendItem($"... on {subTypeName}{{{propertyBuilder}}}");
186188
return this;
187189
}
188190
/// <summary>
@@ -198,6 +200,15 @@ public FragmentBuilder<T> Inline<TSub>(params Expression<Func<TSub, Recursion>>[
198200
Recursive<TSub>(fieldSelectors.Select(selector => paser.GetReturnType(selector)).ToArray());
199201
return this;
200202
}
203+
public FragmentBuilder<T> AddFragment<TProp>(Expression<Func<T, TProp>> fieldSelector, FragmentBuilder<TProp> fragment)
204+
{
205+
fieldSelector.ValidateNotNullArgument(nameof(fieldSelector));
206+
fragment.ValidateNotNullArgument(nameof(fragment));
207+
208+
var fieldPath = fieldSelector.GetFieldPath();
209+
base.AddFragment(fieldPath, fragment);
210+
return this;
211+
}
201212
public override GraphQLRequest GetQuery()
202213
{
203214
_query.Query = $"fragment {_query.OperationName} on {typeof(T).Name} {graphObject}";

APIs/src/EpiServer.ContentGraph/Api/Querying/TypeQueryBuilder.cs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ protected override TypeQueryBuilder<T> AddFragment(FragmentBuilder fragment)
7373
base.AddFragment(fragment);
7474
return this;
7575
}
76+
public TypeQueryBuilder<T> AddFragment<TProp>(Expression<Func<T, TProp>> fieldSelector, FragmentBuilder<TProp> fragment)
77+
{
78+
fieldSelector.ValidateNotNullArgument(nameof(fieldSelector));
79+
fragment.ValidateNotNullArgument(nameof(fragment));
80+
81+
var fieldPath = fieldSelector.GetFieldPath();
82+
base.AddFragment(fieldPath, fragment);
83+
return this;
84+
}
85+
7686
public override TypeQueryBuilder<T> Field(string propertyName)
7787
{
7888
base.Field(propertyName);
@@ -146,10 +156,7 @@ public TypeQueryBuilder<T> NestedFields<TField>(Expression<Func<T, IEnumerable<T
146156
public TypeQueryBuilder<T> AsType<TSub>(string propertyName) where TSub : T
147157
{
148158
string subTypeName = typeof(TSub).Name;
149-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
150-
$"... on {subTypeName}{{{ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName)}}}" :
151-
$" ... on {subTypeName}{{{ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName)}}}"
152-
);
159+
AppendItem($"... on {subTypeName}{{{ConvertNestedFieldToString.ConvertNestedFieldForQuery(propertyName)}}}");
153160
return this;
154161
}
155162
[Obsolete("Obsoleted. Use InlineFragment instead")]
@@ -173,10 +180,7 @@ public TypeQueryBuilder<T> AsType<TSub>(params Expression<Func<TSub, object>>[]
173180

174181
}
175182
string subTypeName = typeof(TSub).Name;
176-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
177-
$"... on {subTypeName}{{{propertyName}}}" :
178-
$" ... on {subTypeName}{{{propertyName}}}"
179-
);
183+
AppendItem($"... on {subTypeName}{{{propertyName}}}");
180184
return this;
181185
}
182186
[Obsolete("Obsoleted. Use InlineFragment instead")]
@@ -191,10 +195,7 @@ public TypeQueryBuilder<T> AsType<TSub>(SubTypeQueryBuilder<TSub> subTypeQuery)
191195
subTypeQuery.ValidateNotNullArgument("subTypeQuery");
192196
subTypeQuery.Parent = this.Parent;
193197
string subTypeName = typeof(TSub).Name;
194-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
195-
$"... on {subTypeName}{subTypeQuery.GetQuery().Query}" :
196-
$" ... on {subTypeName}{subTypeQuery.GetQuery().Query}"
197-
);
198+
AppendItem($"... on {subTypeName}{subTypeQuery.GetQuery().Query}");
198199
return this;
199200
}
200201
public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, string>>[] fieldSelectors) where TSub : T
@@ -211,10 +212,7 @@ public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, str
211212

212213
}
213214
string subTypeName = typeof(TSub).Name;
214-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
215-
$"... on {subTypeName}{{{propertyName}}}" :
216-
$" ... on {subTypeName}{{{propertyName}}}"
217-
);
215+
AppendItem($"... on {subTypeName}{{{propertyName}}}");
218216
return this;
219217
}
220218
public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, int>>[] fieldSelectors) where TSub : T
@@ -231,10 +229,7 @@ public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, int
231229

232230
}
233231
string subTypeName = typeof(TSub).Name;
234-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
235-
$"... on {subTypeName}{{{propertyName}}}" :
236-
$" ... on {subTypeName}{{{propertyName}}}"
237-
);
232+
AppendItem($"... on {subTypeName}{{{propertyName}}}");
238233
return this;
239234
}
240235
public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, double>>[] fieldSelectors) where TSub : T
@@ -251,10 +246,7 @@ public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, dou
251246

252247
}
253248
string subTypeName = typeof(TSub).Name;
254-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
255-
$"... on {subTypeName}{{{propertyName}}}" :
256-
$" ... on {subTypeName}{{{propertyName}}}"
257-
);
249+
AppendItem($"... on {subTypeName}{{{propertyName}}}");
258250
return this;
259251
}
260252
public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, IEnumerable<string>>>[] fieldSelectors) where TSub : T
@@ -271,10 +263,7 @@ public TypeQueryBuilder<T> InlineFragment<TSub>(params Expression<Func<TSub, IEn
271263

272264
}
273265
string subTypeName = typeof(TSub).Name;
274-
graphObject.SelectItems.Append(graphObject.SelectItems.Length == 0 ?
275-
$"... on {subTypeName}{{{propertyName}}}" :
276-
$" ... on {subTypeName}{{{propertyName}}}"
277-
);
266+
AppendItem($"... on {subTypeName}{{{propertyName}}}");
278267
return this;
279268
}
280269
public TypeQueryBuilder<T> Autocomplete(Expression<Func<T, object>> fieldSelector, AutoCompleteOperators autocomplete)

0 commit comments

Comments
 (0)