@@ -57,7 +57,7 @@ public RootNode<TEntity> CreateRootNode<TEntity>(IEnumerable<TEntity> rootEntiti
57
57
_processedEntities = new Dictionary < DependentType , HashSet < IIdentifiable > > ( ) ;
58
58
RegisterRelationshipProxies ( typeof ( TEntity ) ) ;
59
59
var uniqueEntities = ProcessEntities ( rootEntities ) ;
60
- var relationshipsToNextLayer = GetRelationships ( typeof ( TEntity ) ) ;
60
+ var relationshipsToNextLayer = GetPopulatedRelationships ( typeof ( TEntity ) , uniqueEntities . Cast < IIdentifiable > ( ) ) ;
61
61
return new RootNode < TEntity > ( uniqueEntities , relationshipsToNextLayer ) ;
62
62
}
63
63
@@ -80,30 +80,38 @@ public EntityChildLayer CreateNextLayer(IEnumerable<IEntityNode> nodes)
80
80
{
81
81
/// first extract entities by parsing populated relationships in the entities
82
82
/// of previous layer
83
- ( var dependents , var principals ) = ExtractEntities ( nodes ) ;
83
+ ( var principals , var dependents ) = ExtractEntities ( nodes ) ;
84
84
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 ) ;
87
89
88
90
/// convert the groups into child nodes
89
- var nextNodes = dependentsGrouped . Select ( entry =>
91
+ var nextNodes = principalsGrouped . Select ( entry =>
90
92
{
91
93
var nextNodeType = entry . Key ;
94
+ var populatedRelationships = new List < RelationshipProxy > ( ) ;
92
95
var relationshipsToPreviousLayer = entry . Value . Select ( grouped =>
93
96
{
94
97
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 ] ) ;
96
100
} ) . ToList ( ) ;
97
101
98
102
RegisterRelationshipProxies ( nextNodeType ) ;
99
- return CreateNodeInstance ( nextNodeType , GetRelationships ( nextNodeType ) , relationshipsToPreviousLayer ) ;
103
+ return CreateNodeInstance ( nextNodeType , populatedRelationships . ToArray ( ) , relationshipsToPreviousLayer ) ;
100
104
} ) . ToList ( ) ;
101
105
102
106
/// wrap the child nodes in a EntityChildLayer
103
107
return new EntityChildLayer ( nextNodes ) ;
104
108
}
105
109
106
110
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>
107
115
Dictionary < DependentType , List < KeyValuePair < RelationshipProxy , List < IIdentifiable > > > > GroupByDependentTypeOfRelationship ( Dictionary < RelationshipProxy , List < IIdentifiable > > relationships )
108
116
{
109
117
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
115
123
/// </summary>
116
124
( Dictionary < RelationshipProxy , List < IIdentifiable > > , Dictionary < RelationshipProxy , List < IIdentifiable > > ) ExtractEntities ( IEnumerable < IEntityNode > principalNodes )
117
125
{
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
123
128
124
129
foreach ( var node in principalNodes )
125
130
{
@@ -141,36 +146,36 @@ Dictionary<DependentType, List<KeyValuePair<RelationshipProxy, List<IIdentifiabl
141
146
dependentEntities = list ;
142
147
}
143
148
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 ( ) )
146
151
{
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 } ) ;
150
154
}
151
155
}
152
156
}
153
157
}
154
158
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 )
157
161
{
158
162
var type = kvp . Key . DependentType ;
159
163
var list = kvp . Value . Cast ( type ) ;
160
- processEntities . MakeGenericMethod ( type ) . Invoke ( this , new object [ ] { list } ) ;
164
+ processEntitiesMethod . MakeGenericMethod ( type ) . Invoke ( this , new object [ ] { list } ) ;
161
165
}
162
166
163
- return ( principalsGrouped , dependentsGrouped ) ;
167
+ return ( principalsEntitiesGrouped , dependentsEntitiesGrouped ) ;
164
168
}
165
169
166
170
/// <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
168
172
/// principal type to any dependent type
169
173
/// </summary>
170
174
/// <returns>The relationships.</returns>
171
- RelationshipProxy [ ] GetRelationships ( PrincipalType principal )
175
+ RelationshipProxy [ ] GetPopulatedRelationships ( PrincipalType principalType , IEnumerable < IIdentifiable > principals )
172
176
{
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 ( ) ;
174
179
}
175
180
176
181
/// <summary>
@@ -196,8 +201,8 @@ void RegisterRelationshipProxies(DependentType type)
196
201
if ( ! RelationshipProxies . TryGetValue ( attr , out RelationshipProxy proxies ) )
197
202
{
198
203
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 ) ;
201
206
RelationshipProxies [ attr ] = proxy ;
202
207
}
203
208
}
@@ -291,7 +296,7 @@ IRelationshipsFromPreviousLayer CreateRelationshipsFromInstance(DependentType no
291
296
/// <summary>
292
297
/// Reflective helper method to create an instance of <see cref="RelationshipGroup{TDependent}"/>;
293
298
/// </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 )
295
300
{
296
301
var dependentEntitiesHashed = TypeHelper . CreateInstanceOfOpenType ( typeof ( HashSet < > ) , thisLayerType , dependentEntities . Cast ( thisLayerType ) ) ;
297
302
return ( IRelationshipGroup ) TypeHelper . CreateInstanceOfOpenType ( typeof ( RelationshipGroup < > ) ,
0 commit comments