4
4
using System . Linq . Expressions ;
5
5
using JsonApiDotNetCore . Abstractions ;
6
6
using System . Reflection ;
7
+ using JsonApiDotNetCore . Extensions ;
7
8
using JsonApiDotNetCore . Routing ;
8
9
using Microsoft . EntityFrameworkCore ;
9
10
@@ -28,32 +29,53 @@ public object Get(string id)
28
29
var relationalRoute = _context . Route as RelationalRoute ;
29
30
if ( relationalRoute == null )
30
31
{
31
- return GetEntityById ( id ) ;
32
+ return GetEntityById ( _context . Route . BaseModelType , id , null ) ;
32
33
}
33
- return GetRelated ( id , relationalRoute . RelationshipName ) ;
34
+ return GetRelated ( id , relationalRoute ) ;
34
35
}
35
36
36
- private object GetRelated ( string id , string relationshipName )
37
+ private object GetRelated ( string id , RelationalRoute relationalRoute )
37
38
{
38
39
// HACK: this would rely on lazy loading to work...will probably fail
39
- var entity = GetEntityById ( id ) ;
40
- var entityType = entity . GetType ( ) ;
41
- return entityType . GetProperties ( ) . FirstOrDefault ( pi => pi . Name == relationshipName ) . GetValue ( entity ) ;
40
+ var entity = GetEntityById ( relationalRoute . RelationalType , id , relationalRoute . RelationshipName ) ;
41
+ return relationalRoute . RelationalType . GetProperties ( ) . FirstOrDefault ( pi => pi . Name . ToCamelCase ( ) == relationalRoute . RelationshipName . ToCamelCase ( ) ) . GetValue ( entity ) ;
42
42
}
43
43
44
- private object GetDbSetFromContext ( string propName )
44
+
45
+ private IQueryable GetDbSetFromContext ( string propName )
45
46
{
46
47
var dbContext = _context . DbContext ;
47
- return dbContext . GetType ( ) . GetProperties ( ) . FirstOrDefault ( pI => pI . Name == propName ) ? . GetValue ( dbContext , null ) ;
48
+ return ( IQueryable ) dbContext . GetType ( ) . GetProperties ( ) . FirstOrDefault ( pI => pI . Name . ToCamelCase ( ) == propName ) ? . GetValue ( dbContext , null ) ;
48
49
}
49
50
50
- private object GetEntityById ( string id )
51
+ private object GetEntityById ( Type modelType , string id , string includedRelationship )
51
52
{
52
53
// HACK: I _believe_ by casting to IEnumerable, we are loading all records into memory, if so... find a better way...
53
54
// Also, we are making a BIG assumption that the resource has an attribute Id and not ResourceId which is allowed by EF
54
- return
55
- ( GetDbSetFromContext ( _context . Route . BaseRouteDefinition . ContextPropertyName ) as IEnumerable < dynamic > ) ?
56
- . FirstOrDefault ( x => x . Id . ToString ( ) == id ) ;
55
+ var methodToCall = typeof ( ResourceRepository ) . GetMethods ( ) . Single ( method => method . Name . Equals ( "GetDbSet" ) ) ;
56
+ var genericMethod = methodToCall . MakeGenericMethod ( modelType ) ;
57
+ genericMethod . Invoke ( genericMethod , null ) ;
58
+ var dbSet = genericMethod . Invoke ( this , null ) ;
59
+
60
+ if ( ! string . IsNullOrEmpty ( includedRelationship ) )
61
+ {
62
+ var includeMethod = typeof ( ResourceRepository ) . GetMethods ( ) . Single ( method => method . Name . Equals ( "IncludeEntity" ) ) ;
63
+ var genericIncludeMethod = includeMethod . MakeGenericMethod ( modelType ) ;
64
+ genericIncludeMethod . Invoke ( genericMethod , null ) ;
65
+ dbSet = genericIncludeMethod . Invoke ( this , new [ ] { dbSet , includedRelationship } ) ;
66
+ }
67
+
68
+ return ( dbSet as IEnumerable < dynamic > ) . SingleOrDefault ( x => x . Id . ToString ( ) == id ) ;
69
+ }
70
+
71
+ private DbSet < T > GetDbSet < T > ( ) where T : class
72
+ {
73
+ return ( ( DbContext ) _context . DbContext ) . Set < T > ( ) ;
74
+ }
75
+
76
+ private IQueryable < T > IncludeEntity < T > ( IQueryable < T > queryable , string includedEntityName ) where T : class
77
+ {
78
+ return queryable . Include ( includedEntityName ) ;
57
79
}
58
80
}
59
81
}
0 commit comments