@@ -16,7 +16,7 @@ public interface IGenericProcessor
16
16
void SetRelationships ( object parent , RelationshipAttribute relationship , IEnumerable < string > relationshipIds ) ;
17
17
}
18
18
19
- public class GenericProcessor < T > : IGenericProcessor where T : class , IIdentifiable
19
+ public class GenericProcessor < T > : IGenericProcessor where T : class
20
20
{
21
21
private readonly DbContext _context ;
22
22
public GenericProcessor ( IDbContextResolver contextResolver )
@@ -33,39 +33,51 @@ public virtual async Task UpdateRelationshipsAsync(object parent, RelationshipAt
33
33
34
34
public virtual void SetRelationships ( object parent , RelationshipAttribute relationship , IEnumerable < string > relationshipIds )
35
35
{
36
- if ( relationship is HasManyThroughAttribute hasManyThrough )
36
+ if ( relationship is HasManyThroughAttribute hasManyThrough && parent is IIdentifiable identifiableParent )
37
37
{
38
- var parentId = ( ( IIdentifiable ) parent ) . StringId ;
39
- ParameterExpression parameter = Expression . Parameter ( hasManyThrough . Type ) ;
40
- Expression property = Expression . Property ( parameter , hasManyThrough . LeftProperty ) ;
38
+ // ArticleTag
39
+ ParameterExpression parameter = Expression . Parameter ( hasManyThrough . ThroughType ) ;
40
+
41
+ // ArticleTag.ArticleId
42
+ Expression property = Expression . Property ( parameter , hasManyThrough . LeftIdProperty ) ;
43
+
44
+ // article.Id
45
+ var parentId = TypeHelper . ConvertType ( identifiableParent . StringId , hasManyThrough . LeftIdProperty . PropertyType ) ;
41
46
Expression target = Expression . Constant ( parentId ) ;
42
- Expression toString = Expression . Call ( property , "ToString" , null , null ) ;
43
- Expression equals = Expression . Call ( toString , "Equals" , null , target ) ;
44
- Expression < Func < object , bool > > lambda = Expression . Lambda < Func < object , bool > > ( equals , parameter ) ;
47
+
48
+ // ArticleTag.ArticleId.Equals(article.Id)
49
+ Expression equals = Expression . Call ( property , "Equals" , null , target ) ;
50
+
51
+ var lambda = Expression . Lambda < Func < T , bool > > ( equals , parameter ) ;
45
52
46
53
var oldLinks = _context
47
- . Set ( hasManyThrough . ThroughType )
54
+ . Set < T > ( )
48
55
. Where ( lambda . Compile ( ) )
49
56
. ToList ( ) ;
50
57
51
- _context . Remove ( oldLinks ) ;
58
+ // TODO: we shouldn't need to do this and it especially shouldn't happen outside a transaction
59
+ // instead we should try updating the existing?
60
+ _context . RemoveRange ( oldLinks ) ;
52
61
53
62
var newLinks = relationshipIds . Select ( x => {
54
63
var link = Activator . CreateInstance ( hasManyThrough . ThroughType ) ;
55
- hasManyThrough . LeftProperty . SetValue ( link , TypeHelper . ConvertType ( parent , hasManyThrough . LeftProperty . PropertyType ) ) ;
56
- hasManyThrough . RightProperty . SetValue ( link , TypeHelper . ConvertType ( x , hasManyThrough . RightProperty . PropertyType ) ) ;
64
+ hasManyThrough . LeftIdProperty . SetValue ( link , TypeHelper . ConvertType ( parentId , hasManyThrough . LeftIdProperty . PropertyType ) ) ;
65
+ hasManyThrough . RightIdProperty . SetValue ( link , TypeHelper . ConvertType ( x , hasManyThrough . RightIdProperty . PropertyType ) ) ;
57
66
return link ;
58
67
} ) ;
68
+
59
69
_context . AddRange ( newLinks ) ;
60
70
}
61
71
else if ( relationship . IsHasMany )
62
72
{
63
- var entities = _context . Set < T > ( ) . Where ( x => relationshipIds . Contains ( x . StringId ) ) . ToList ( ) ;
73
+ // TODO: need to handle the failure mode when the relationship does not implement IIdentifiable
74
+ var entities = _context . Set < T > ( ) . Where ( x => relationshipIds . Contains ( ( ( IIdentifiable ) x ) . StringId ) ) . ToList ( ) ;
64
75
relationship . SetValue ( parent , entities ) ;
65
76
}
66
77
else
67
78
{
68
- var entity = _context . Set < T > ( ) . SingleOrDefault ( x => relationshipIds . First ( ) == x . StringId ) ;
79
+ // TODO: need to handle the failure mode when the relationship does not implement IIdentifiable
80
+ var entity = _context . Set < T > ( ) . SingleOrDefault ( x => relationshipIds . First ( ) == ( ( IIdentifiable ) x ) . StringId ) ;
69
81
relationship . SetValue ( parent , entity ) ;
70
82
}
71
83
}
0 commit comments