@@ -24,6 +24,7 @@ public class EntityFrameworkPayloadMaterializer<T> : IPayloadMaterializer<T> whe
2424 private readonly IQueryableResourceCollectionPayloadBuilder _queryableResourceCollectionPayloadBuilder ;
2525 private readonly ISingleResourcePayloadBuilder _singleResourcePayloadBuilder ;
2626 private readonly MethodInfo _getRelatedToManyMethod ;
27+ private readonly MethodInfo _getRelatedToOneMethod ;
2728
2829 /// <summary>
2930 /// Creates a new EntityFrameworkPayloadMaterializer
@@ -44,6 +45,8 @@ public EntityFrameworkPayloadMaterializer(
4445 _singleResourcePayloadBuilder = singleResourcePayloadBuilder ;
4546 _getRelatedToManyMethod = GetType ( )
4647 . GetMethod ( "GetRelatedToMany" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
48+ _getRelatedToOneMethod = GetType ( )
49+ . GetMethod ( "GetRelatedToOne" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
4750 }
4851
4952 public virtual Task < IResourceCollectionPayload > GetRecords ( HttpRequestMessage request , CancellationToken cancellationToken )
@@ -62,7 +65,6 @@ public virtual async Task<ISingleResourcePayload> GetRecordById(string id, HttpR
6265 public virtual async Task < IJsonApiPayload > GetRelated ( string id , string relationshipKey , HttpRequestMessage request ,
6366 CancellationToken cancellationToken )
6467 {
65- var apiBaseUrl = GetBaseUrlFromRequest ( request ) ;
6668 var registration = _resourceTypeRegistry . GetRegistrationForType ( typeof ( T ) ) ;
6769 var relationship = ( ResourceTypeRelationship ) registration . GetFieldByName ( relationshipKey ) ;
6870
@@ -74,7 +76,9 @@ public virtual async Task<IJsonApiPayload> GetRelated(string id, string relation
7476 }
7577 else
7678 {
77- throw new NotImplementedException ( ) ;
79+ var method = _getRelatedToOneMethod . MakeGenericMethod ( relationship . RelatedType ) ;
80+ var result = ( Task < ISingleResourcePayload > ) method . Invoke ( this , new object [ ] { id , relationship , request , cancellationToken } ) ;
81+ return await result ;
7882 }
7983 }
8084
@@ -143,6 +147,19 @@ private async Task<IResourceCollectionPayload> GetRelatedToMany<TRelated>(string
143147 return await _queryableResourceCollectionPayloadBuilder . BuildPayload ( relatedResourceQuery , request , cancellationToken ) ;
144148 }
145149
150+ // ReSharper disable once UnusedMember.Local
151+ private async Task < ISingleResourcePayload > GetRelatedToOne < TRelated > ( string id ,
152+ ResourceTypeRelationship relationship , HttpRequestMessage request , CancellationToken cancellationToken )
153+ {
154+ var param = Expression . Parameter ( typeof ( T ) ) ;
155+ var accessorExpr = Expression . Property ( param , relationship . Property ) ;
156+ var lambda = Expression . Lambda < Func < T , TRelated > > ( accessorExpr , param ) ;
157+
158+ var primaryEntityQuery = FilterById < T > ( id ) ;
159+ var relatedResource = await primaryEntityQuery . Select ( lambda ) . FirstOrDefaultAsync ( cancellationToken ) ;
160+ return _singleResourcePayloadBuilder . BuildPayload ( relatedResource , GetBaseUrlFromRequest ( request ) , null ) ;
161+ }
162+
146163 private IQueryable < TResource > Filter < TResource > ( Expression < Func < TResource , bool > > predicate ,
147164 params Expression < Func < TResource , object > > [ ] includes ) where TResource : class
148165 {
0 commit comments