@@ -19,6 +19,22 @@ public FieldBuilder<object, TReturn> AddFirstField<TReturn>(
1919 return new FieldBuilderEx < object , TReturn > ( field ) ;
2020 }
2121
22+ public FieldBuilder < object , TReturn > AddFirstField < TReturn > (
23+ IObjectGraphType graph ,
24+ string name ,
25+ Func < ResolveEfFieldContext < TDbContext , object > , Task < IQueryable < TReturn > > > resolve ,
26+ Func < ResolveEfFieldContext < TDbContext , object > , TReturn , Task > ? mutate = null ,
27+ Type ? graphType = null ,
28+ bool nullable = false ,
29+ bool omitQueryArguments = false ,
30+ bool idOnly = false )
31+ where TReturn : class
32+ {
33+ var field = BuildFirstField ( name , resolve , mutate , graphType , nullable , omitQueryArguments , idOnly ) ;
34+ graph . AddField ( field ) ;
35+ return new FieldBuilderEx < object , TReturn > ( field ) ;
36+ }
37+
2238 public FieldBuilder < object , TReturn > AddFirstField < TReturn > (
2339 IComplexGraphType graph ,
2440 string name ,
@@ -35,6 +51,22 @@ public FieldBuilder<object, TReturn> AddFirstField<TReturn>(
3551 return new FieldBuilderEx < object , TReturn > ( field ) ;
3652 }
3753
54+ public FieldBuilder < object , TReturn > AddFirstField < TReturn > (
55+ IComplexGraphType graph ,
56+ string name ,
57+ Func < ResolveEfFieldContext < TDbContext , object > , Task < IQueryable < TReturn > > > resolve ,
58+ Func < ResolveEfFieldContext < TDbContext , object > , TReturn , Task > ? mutate = null ,
59+ Type ? graphType = null ,
60+ bool nullable = false ,
61+ bool omitQueryArguments = false ,
62+ bool idOnly = false )
63+ where TReturn : class
64+ {
65+ var field = BuildFirstField ( name , resolve , mutate , graphType , nullable , omitQueryArguments , idOnly ) ;
66+ graph . AddField ( field ) ;
67+ return new FieldBuilderEx < object , TReturn > ( field ) ;
68+ }
69+
3870 public FieldBuilder < TSource , TReturn > AddFirstField < TSource , TReturn > (
3971 IComplexGraphType graph ,
4072 string name ,
@@ -51,6 +83,22 @@ public FieldBuilder<TSource, TReturn> AddFirstField<TSource, TReturn>(
5183 return new FieldBuilderEx < TSource , TReturn > ( field ) ;
5284 }
5385
86+ public FieldBuilder < TSource , TReturn > AddFirstField < TSource , TReturn > (
87+ IComplexGraphType graph ,
88+ string name ,
89+ Func < ResolveEfFieldContext < TDbContext , TSource > , Task < IQueryable < TReturn > > > resolve ,
90+ Func < ResolveEfFieldContext < TDbContext , TSource > , TReturn , Task > ? mutate = null ,
91+ Type ? graphType = null ,
92+ bool nullable = false ,
93+ bool omitQueryArguments = false ,
94+ bool idOnly = false )
95+ where TReturn : class
96+ {
97+ var field = BuildFirstField ( name , resolve , mutate , graphType , nullable , omitQueryArguments , idOnly ) ;
98+ graph . AddField ( field ) ;
99+ return new FieldBuilderEx < TSource , TReturn > ( field ) ;
100+ }
101+
54102 FieldType BuildFirstField < TSource , TReturn > (
55103 string name ,
56104 Func < ResolveEfFieldContext < TDbContext , TSource > , IQueryable < TReturn > > resolve ,
@@ -60,6 +108,28 @@ FieldType BuildFirstField<TSource, TReturn>(
60108 bool omitQueryArguments ,
61109 bool idOnly )
62110 where TReturn : class
111+ => BuildFirstField (
112+ name ,
113+ _ =>
114+ {
115+ var queryable = resolve ( _ ) ;
116+ return Task . FromResult ( queryable ) ;
117+ } ,
118+ mutate ,
119+ graphType ,
120+ nullable ,
121+ omitQueryArguments ,
122+ idOnly ) ;
123+
124+ FieldType BuildFirstField < TSource , TReturn > (
125+ string name ,
126+ Func < ResolveEfFieldContext < TDbContext , TSource > , Task < IQueryable < TReturn > > > resolve ,
127+ Func < ResolveEfFieldContext < TDbContext , TSource > , TReturn , Task > ? mutate ,
128+ Type ? graphType ,
129+ bool nullable ,
130+ bool omitQueryArguments ,
131+ bool idOnly )
132+ where TReturn : class
63133 {
64134 Guard . AgainstWhiteSpace ( nameof ( name ) , name ) ;
65135
@@ -71,79 +141,78 @@ FieldType BuildFirstField<TSource, TReturn>(
71141 {
72142 Name = name ,
73143 Type = graphType ,
74- Resolver = new FuncFieldResolver < TSource , TReturn ? > (
75- async context =>
76- {
77- var efFieldContext = BuildContext ( context ) ;
144+ Resolver = new FuncFieldResolver < TSource , TReturn ? > ( async context =>
145+ {
146+ var efFieldContext = BuildContext ( context ) ;
78147
79- var query = resolve ( efFieldContext ) ;
80- if ( disableTracking )
81- {
82- query = query . AsNoTracking ( ) ;
83- }
148+ var query = await resolve ( efFieldContext ) ;
149+ if ( disableTracking )
150+ {
151+ query = query . AsNoTracking ( ) ;
152+ }
84153
85- query = includeAppender . AddIncludes ( query , context ) ;
86- query = query . ApplyGraphQlArguments ( context , names , false , omitQueryArguments ) ;
154+ query = includeAppender . AddIncludes ( query , context ) ;
155+ query = query . ApplyGraphQlArguments ( context , names , false , omitQueryArguments ) ;
87156
88- QueryLogger . Write ( query ) ;
157+ QueryLogger . Write ( query ) ;
89158
90- TReturn ? first ;
91- try
92- {
93- if ( disableAsync )
94- {
95- first = query . FirstOrDefault ( ) ;
96- }
97- else
98- {
99- first = await query . FirstOrDefaultAsync ( context . CancellationToken ) ;
100- }
101- }
102- catch ( TaskCanceledException )
103- {
104- throw ;
105- }
106- catch ( OperationCanceledException )
159+ TReturn ? first ;
160+ try
161+ {
162+ if ( disableAsync )
107163 {
108- throw ;
164+ first = query . FirstOrDefault ( ) ;
109165 }
110- catch ( Exception exception )
166+ else
111167 {
112- throw new (
113- $ """
114- Failed to execute query for field `{ name } `
115- GraphType: { graphType . FullName }
116- TSource: { typeof ( TSource ) . FullName }
117- TReturn: { typeof ( TReturn ) . FullName }
118- DisableAsync: { disableAsync }
119- OmitQueryArguments: { omitQueryArguments }
120- Nullable: { nullable }
121- KeyNames: { JoinKeys ( names ) }
122- Query: { query . ToQueryString ( ) }
123- """ ,
124- exception ) ;
168+ first = await query . FirstOrDefaultAsync ( context . CancellationToken ) ;
125169 }
126-
127- if ( first is not null )
170+ }
171+ catch ( TaskCanceledException )
172+ {
173+ throw ;
174+ }
175+ catch ( OperationCanceledException )
176+ {
177+ throw ;
178+ }
179+ catch ( Exception exception )
180+ {
181+ throw new (
182+ $ """
183+ Failed to execute query for field `{ name } `
184+ GraphType: { graphType . FullName }
185+ TSource: { typeof ( TSource ) . FullName }
186+ TReturn: { typeof ( TReturn ) . FullName }
187+ DisableAsync: { disableAsync }
188+ OmitQueryArguments: { omitQueryArguments }
189+ Nullable: { nullable }
190+ KeyNames: { JoinKeys ( names ) }
191+ Query: { query . ToQueryString ( ) }
192+ """ ,
193+ exception ) ;
194+ }
195+
196+ if ( first is not null )
197+ {
198+ if ( await efFieldContext . Filters . ShouldInclude ( context . UserContext , context . User , first ) )
128199 {
129- if ( await efFieldContext . Filters . ShouldInclude ( context . UserContext , context . User , first ) )
200+ if ( mutate is not null )
130201 {
131- if ( mutate is not null )
132- {
133- await mutate . Invoke ( efFieldContext , first ) ;
134- }
135-
136- return first ;
202+ await mutate . Invoke ( efFieldContext , first ) ;
137203 }
138- }
139204
140- if ( nullable )
141- {
142- return null ;
205+ return first ;
143206 }
207+ }
208+
209+ if ( nullable )
210+ {
211+ return null ;
212+ }
144213
145- throw new FirstEntityNotFoundException ( ) ;
146- } )
214+ throw new FirstEntityNotFoundException ( ) ;
215+ } )
147216 } ;
148217
149218 if ( ! omitQueryArguments )
0 commit comments