@@ -57,7 +57,7 @@ public RootNode<TEntity> CreateRootNode<TEntity>(IEnumerable<TEntity> rootEntiti
5757 _processedEntities = new Dictionary < DependentType , HashSet < IIdentifiable > > ( ) ;
5858 RegisterRelationshipProxies ( typeof ( TEntity ) ) ;
5959 var uniqueEntities = ProcessEntities ( rootEntities ) ;
60- var relationshipsToNextLayer = GetRelationships ( typeof ( TEntity ) ) ;
60+ var relationshipsToNextLayer = GetPopulatedRelationships ( typeof ( TEntity ) , uniqueEntities . Cast < IIdentifiable > ( ) ) ;
6161 return new RootNode < TEntity > ( uniqueEntities , relationshipsToNextLayer ) ;
6262 }
6363
@@ -80,30 +80,38 @@ public EntityChildLayer CreateNextLayer(IEnumerable<IEntityNode> nodes)
8080 {
8181 /// first extract entities by parsing populated relationships in the entities
8282 /// of previous layer
83- ( var dependents , var principals ) = ExtractEntities ( nodes ) ;
83+ ( var principals , var dependents ) = ExtractEntities ( nodes ) ;
8484
85- /// group them conveniently so we can make ChildNodes of them
86- var dependentsGrouped = GroupByDependentTypeOfRelationship ( dependents ) ;
85+ /// group them conveniently so we can make ChildNodes of them:
86+ /// there might be several relationship attributes in dependents dictionary
87+ /// that point to the same dependent type.
88+ var principalsGrouped = GroupByDependentTypeOfRelationship ( principals ) ;
8789
8890 /// convert the groups into child nodes
89- var nextNodes = dependentsGrouped . Select ( entry =>
91+ var nextNodes = principalsGrouped . Select ( entry =>
9092 {
9193 var nextNodeType = entry . Key ;
94+ var populatedRelationships = new List < RelationshipProxy > ( ) ;
9295 var relationshipsToPreviousLayer = entry . Value . Select ( grouped =>
9396 {
9497 var proxy = grouped . Key ;
95- return CreateRelationsipGroupInstance ( nextNodeType , proxy , grouped . Value , principals [ proxy ] ) ;
98+ populatedRelationships . AddRange ( GetPopulatedRelationships ( nextNodeType , dependents [ proxy ] ) ) ;
99+ return CreateRelationshipGroupInstance ( nextNodeType , proxy , grouped . Value , dependents [ proxy ] ) ;
96100 } ) . ToList ( ) ;
97101
98102 RegisterRelationshipProxies ( nextNodeType ) ;
99- return CreateNodeInstance ( nextNodeType , GetRelationships ( nextNodeType ) , relationshipsToPreviousLayer ) ;
103+ return CreateNodeInstance ( nextNodeType , populatedRelationships . ToArray ( ) , relationshipsToPreviousLayer ) ;
100104 } ) . ToList ( ) ;
101105
102106 /// wrap the child nodes in a EntityChildLayer
103107 return new EntityChildLayer ( nextNodes ) ;
104108 }
105109
106110
111+ /// <summary>
112+ /// iterates throug the <paramref name="relationships"/> dictinary and groups the values
113+ /// by matching dependent type of the keys (which are relationshipattributes)
114+ /// </summary>
107115 Dictionary < DependentType , List < KeyValuePair < RelationshipProxy , List < IIdentifiable > > > > GroupByDependentTypeOfRelationship ( Dictionary < RelationshipProxy , List < IIdentifiable > > relationships )
108116 {
109117 return relationships . GroupBy ( kvp => kvp . Key . DependentType ) . ToDictionary ( gdc => gdc . Key , gdc => gdc . ToList ( ) ) ;
@@ -115,11 +123,8 @@ Dictionary<DependentType, List<KeyValuePair<RelationshipProxy, List<IIdentifiabl
115123 /// </summary>
116124 ( Dictionary < RelationshipProxy , List < IIdentifiable > > , Dictionary < RelationshipProxy , List < IIdentifiable > > ) ExtractEntities ( IEnumerable < IEntityNode > principalNodes )
117125 {
118- var currentLayerEntities = new List < IIdentifiable > ( ) ;
119- var principalsGrouped = new Dictionary < RelationshipProxy , List < IIdentifiable > > ( ) ;
120- var dependentsGrouped = new Dictionary < RelationshipProxy , List < IIdentifiable > > ( ) ;
121-
122- principalNodes . ForEach ( n => RegisterRelationshipProxies ( n . EntityType ) ) ;
126+ var principalsEntitiesGrouped = new Dictionary < RelationshipProxy , List < IIdentifiable > > ( ) ; // RelationshipAttr_prevlayer->currentlayer => prevLayerEntities
127+ var dependentsEntitiesGrouped = new Dictionary < RelationshipProxy , List < IIdentifiable > > ( ) ; // RelationshipAttr_prevlayer->currentlayer => currentLayerEntities
123128
124129 foreach ( var node in principalNodes )
125130 {
@@ -141,36 +146,36 @@ Dictionary<DependentType, List<KeyValuePair<RelationshipProxy, List<IIdentifiabl
141146 dependentEntities = list ;
142147 }
143148
144- var newDependentEntities = UniqueInTree ( dependentEntities . Cast < IIdentifiable > ( ) , proxy . DependentType ) ;
145- if ( proxy . IsContextRelation || newDependentEntities . Any ( ) )
149+ var uniqueDependentEntities = UniqueInTree ( dependentEntities . Cast < IIdentifiable > ( ) , proxy . DependentType ) ;
150+ if ( proxy . IsContextRelation || uniqueDependentEntities . Any ( ) )
146151 {
147- currentLayerEntities . AddRange ( newDependentEntities ) ;
148- AddToRelationshipGroup ( dependentsGrouped , proxy , newDependentEntities ) ; // TODO check if this needs to be newDependentEntities or just dependentEntities
149- AddToRelationshipGroup ( principalsGrouped , proxy , new IIdentifiable [ ] { principalEntity } ) ;
152+ AddToRelationshipGroup ( dependentsEntitiesGrouped , proxy , uniqueDependentEntities ) ;
153+ AddToRelationshipGroup ( principalsEntitiesGrouped , proxy , new IIdentifiable [ ] { principalEntity } ) ;
150154 }
151155 }
152156 }
153157 }
154158
155- var processEntities = GetType ( ) . GetMethod ( nameof ( ProcessEntities ) , BindingFlags . NonPublic | BindingFlags . Instance ) ;
156- foreach ( var kvp in dependentsGrouped )
159+ var processEntitiesMethod = GetType ( ) . GetMethod ( nameof ( ProcessEntities ) , BindingFlags . NonPublic | BindingFlags . Instance ) ;
160+ foreach ( var kvp in dependentsEntitiesGrouped )
157161 {
158162 var type = kvp . Key . DependentType ;
159163 var list = kvp . Value . Cast ( type ) ;
160- processEntities . MakeGenericMethod ( type ) . Invoke ( this , new object [ ] { list } ) ;
164+ processEntitiesMethod . MakeGenericMethod ( type ) . Invoke ( this , new object [ ] { list } ) ;
161165 }
162166
163- return ( principalsGrouped , dependentsGrouped ) ;
167+ return ( principalsEntitiesGrouped , dependentsEntitiesGrouped ) ;
164168 }
165169
166170 /// <summary>
167- /// Get all relationships known in the current tree traversal from a
171+ /// Get all populated relationships known in the current tree traversal from a
168172 /// principal type to any dependent type
169173 /// </summary>
170174 /// <returns>The relationships.</returns>
171- RelationshipProxy [ ] GetRelationships ( PrincipalType principal )
175+ RelationshipProxy [ ] GetPopulatedRelationships ( PrincipalType principalType , IEnumerable < IIdentifiable > principals )
172176 {
173- return RelationshipProxies . Select ( entry => entry . Value ) . Where ( proxy => proxy . PrincipalType == principal ) . ToArray ( ) ;
177+ var relationshipsFromPrincipalToDependent = RelationshipProxies . Select ( entry => entry . Value ) . Where ( proxy => proxy . PrincipalType == principalType ) ;
178+ return relationshipsFromPrincipalToDependent . Where ( proxy => proxy . IsContextRelation || principals . Any ( p => proxy . GetValue ( p ) != null ) ) . ToArray ( ) ;
174179 }
175180
176181 /// <summary>
@@ -196,8 +201,8 @@ void RegisterRelationshipProxies(DependentType type)
196201 if ( ! RelationshipProxies . TryGetValue ( attr , out RelationshipProxy proxies ) )
197202 {
198203 DependentType dependentType = GetDependentTypeFromRelationship ( attr ) ;
199- var isContextRelation = _context . RelationshipsToUpdate ? . ContainsKey ( attr ) ;
200- var proxy = new RelationshipProxy ( attr , dependentType , isContextRelation != null && ( bool ) isContextRelation ) ;
204+ var isContextRelation = ( _context . RelationshipsToUpdate ? . ContainsKey ( attr ) ) != null ;
205+ var proxy = new RelationshipProxy ( attr , dependentType , isContextRelation ) ;
201206 RelationshipProxies [ attr ] = proxy ;
202207 }
203208 }
@@ -291,7 +296,7 @@ IRelationshipsFromPreviousLayer CreateRelationshipsFromInstance(DependentType no
291296 /// <summary>
292297 /// Reflective helper method to create an instance of <see cref="RelationshipGroup{TDependent}"/>;
293298 /// </summary>
294- IRelationshipGroup CreateRelationsipGroupInstance ( Type thisLayerType , RelationshipProxy proxy , List < IIdentifiable > principalEntities , List < IIdentifiable > dependentEntities )
299+ IRelationshipGroup CreateRelationshipGroupInstance ( Type thisLayerType , RelationshipProxy proxy , List < IIdentifiable > principalEntities , List < IIdentifiable > dependentEntities )
295300 {
296301 var dependentEntitiesHashed = TypeHelper . CreateInstanceOfOpenType ( typeof ( HashSet < > ) , thisLayerType , dependentEntities . Cast ( thisLayerType ) ) ;
297302 return ( IRelationshipGroup ) TypeHelper . CreateInstanceOfOpenType ( typeof ( RelationshipGroup < > ) ,
0 commit comments