@@ -16,7 +16,7 @@ public interface IGenericProcessor
1616 void SetRelationships ( object parent , RelationshipAttribute relationship , IEnumerable < string > relationshipIds ) ;
1717 }
1818
19- public class GenericProcessor < T > : IGenericProcessor where T : class , IIdentifiable
19+ public class GenericProcessor < T > : IGenericProcessor where T : class
2020 {
2121 private readonly DbContext _context ;
2222 public GenericProcessor ( IDbContextResolver contextResolver )
@@ -33,39 +33,51 @@ public virtual async Task UpdateRelationshipsAsync(object parent, RelationshipAt
3333
3434 public virtual void SetRelationships ( object parent , RelationshipAttribute relationship , IEnumerable < string > relationshipIds )
3535 {
36- if ( relationship is HasManyThroughAttribute hasManyThrough )
36+ if ( relationship is HasManyThroughAttribute hasManyThrough && parent is IIdentifiable identifiableParent )
3737 {
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 ) ;
4146 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 ) ;
4552
4653 var oldLinks = _context
47- . Set ( hasManyThrough . ThroughType )
54+ . Set < T > ( )
4855 . Where ( lambda . Compile ( ) )
4956 . ToList ( ) ;
5057
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 ) ;
5261
5362 var newLinks = relationshipIds . Select ( x => {
5463 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 ) ) ;
5766 return link ;
5867 } ) ;
68+
5969 _context . AddRange ( newLinks ) ;
6070 }
6171 else if ( relationship . IsHasMany )
6272 {
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 ( ) ;
6475 relationship . SetValue ( parent , entities ) ;
6576 }
6677 else
6778 {
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 ) ;
6981 relationship . SetValue ( parent , entity ) ;
7082 }
7183 }
0 commit comments