@@ -38,31 +38,7 @@ IEnumerator IEnumerable.GetEnumerator()
3838
3939 private IEnumerable < IDictionary < string , object > > CreateObjectGraphs ( )
4040 {
41- var load = new Dictionary < IDictionary < string , object > , IDictionary < string , HashSet < IDictionary < string , object > > > > ( new DictionaryEqualityComparer ( ) ) ;
42-
43- foreach ( var dict in _source )
44- {
45- IDictionary < string , HashSet < IDictionary < string , object > > > children ;
46-
47- var main = new SubDictionary < string , object > ( dict , s => ! s . StartsWith ( "__with__" ) ) ;
48- if ( ! load . TryGetValue ( main , out children ) )
49- {
50- children = new Dictionary < string , HashSet < IDictionary < string , object > > > ( ) ;
51- load . Add ( main , children ) ;
52- }
53-
54- foreach ( var tuple in ExtractObjects ( dict ) )
55- {
56- if ( children . ContainsKey ( tuple . Item1 ) )
57- {
58- children [ tuple . Item1 ] . Add ( tuple . Item2 ) ;
59- }
60- else
61- {
62- children . Add ( tuple . Item1 , new HashSet < IDictionary < string , object > > ( new DictionaryEqualityComparer ( ) ) { tuple . Item2 } ) ;
63- }
64- }
65- }
41+ var load = BuildLoadDictionary ( ) ;
6642
6743 IDictionary < string , int > index = null ;
6844 foreach ( var kvp in load )
@@ -74,128 +50,94 @@ private IEnumerable<IDictionary<string,object>> CreateObjectGraphs()
7450 var row = new OptimizedDictionary < string , object > ( index , kvp . Key . Values ) ;
7551 foreach ( var sub in kvp . Value )
7652 {
77- if ( sub . Value . Count == 1 )
53+ if ( sub . Value . Single != null )
7854 {
79- kvp . Key [ sub . Key ] = sub . Value . Single ( ) ;
55+ row [ sub . Key ] = sub . Value . Single ;
8056 }
81- else
57+ else if ( sub . Value . Collection != null )
8258 {
83- kvp . Key [ sub . Key ] = sub . Value . ToList ( ) ;
59+ row [ sub . Key ] = sub . Value . Collection . ToList ( ) ;
8460 }
8561 }
8662
87- yield return kvp . Key ;
63+ yield return row ;
8864 }
8965 }
9066
91- private IEnumerable < Tuple < string , Dictionary < string , object > > > ExtractObjects ( IDictionary < string , object > source )
92- {
93- var names =
94- source . Keys . Where ( k => k . StartsWith ( "__with__" ) ) . Select (
95- k => k . Split ( new [ ] { "__" } , StringSplitOptions . RemoveEmptyEntries ) [ 1 ] ) . ToList ( ) ;
96-
97- return from name in names
98- let pattern = "__with__" + name + "__"
99- select Tuple . Create ( name , source . Where ( kvp => kvp . Key . StartsWith ( pattern ) )
100- . ToDictionary ( kvp => kvp . Key . Replace ( pattern , "" ) , kvp => kvp . Value ) ) ;
101- }
102- }
103-
104- internal class SubDictionary < TKey , TValue > : IDictionary < TKey , TValue >
105- {
106- private readonly IDictionary < TKey , TValue > _super ;
107- private readonly Func < TKey , bool > _keyFilter ;
108-
109- private IEnumerable < KeyValuePair < TKey , TValue > > Filter ( )
110- {
111- return _super . Where ( kvp => _keyFilter ( kvp . Key ) ) ;
112- }
113-
114- public IEnumerator < KeyValuePair < TKey , TValue > > GetEnumerator ( )
115- {
116- return Filter ( ) . GetEnumerator ( ) ;
117- }
118-
119- public void Add ( KeyValuePair < TKey , TValue > item )
120- {
121- _super . Add ( item ) ;
122- }
123-
124- public void Clear ( )
125- {
126- _super . Clear ( ) ;
127- }
128-
129- public bool Contains ( KeyValuePair < TKey , TValue > item )
130- {
131- return _super . Contains ( item ) ;
132- }
133-
134- public void CopyTo ( KeyValuePair < TKey , TValue > [ ] array , int arrayIndex )
135- {
136- Filter ( ) . ToArray ( ) . CopyTo ( array , arrayIndex ) ;
137- }
138-
139- public bool Remove ( KeyValuePair < TKey , TValue > item )
67+ private Dictionary < IDictionary < string , object > , IDictionary < string , WithContainer > > BuildLoadDictionary ( )
14068 {
141- return _super . Remove ( item ) ;
142- }
69+ var load =
70+ new Dictionary < IDictionary < string , object > , IDictionary < string , WithContainer > > (
71+ new DictionaryEqualityComparer ( ) ) ;
14372
144- public int Count
145- {
146- get { return Filter ( ) . Count ( ) ; }
147- }
73+ foreach ( var dict in _source )
74+ {
75+ IDictionary < string , WithContainer > withContainers ;
14876
149- public bool IsReadOnly
150- {
151- get { return _super . IsReadOnly ; }
152- }
77+ var main = new SubDictionary < string , object > ( dict , s => ! s . StartsWith ( "__with" ) ) ;
78+ if ( ! load . TryGetValue ( main , out withContainers ) )
79+ {
80+ withContainers = new Dictionary < string , WithContainer > ( ) ;
81+ load . Add ( main , withContainers ) ;
82+ foreach ( var tuple in ExtractSingleObjects ( dict ) )
83+ {
84+ var withContainer = new WithContainer ( ) ;
85+ withContainer . SetSingle ( tuple . Item2 ) ;
86+ withContainers . Add ( tuple . Item1 , withContainer ) ;
87+ }
88+ }
15389
154- public bool ContainsKey ( TKey key )
155- {
156- return _keyFilter ( key ) && _super . ContainsKey ( key ) ;
90+ foreach ( var tuple in ExtractCollectionObjects ( dict ) )
91+ {
92+ if ( ! withContainers . ContainsKey ( tuple . Item1 ) )
93+ {
94+ withContainers . Add ( tuple . Item1 , new WithContainer ( ) ) ;
95+ }
96+ withContainers [ tuple . Item1 ] . AddToCollection ( tuple . Item2 ) ;
97+ }
98+ }
99+ return load ;
157100 }
158101
159- public void Add ( TKey key , TValue value )
102+ private class WithContainer
160103 {
161- _super . Add ( key , value ) ;
162- }
104+ public HashSet < IDictionary < string , object > > Collection { get ; private set ; }
163105
164- public bool Remove ( TKey key )
165- {
166- return _super . Remove ( key ) ;
167- }
106+ public IDictionary < string , object > Single { get ; private set ; }
168107
169- public bool TryGetValue ( TKey key , out TValue value )
170- {
171- return _super . TryGetValue ( key , out value ) ;
172- }
108+ public void AddToCollection ( IDictionary < string , object > row )
109+ {
110+ if ( Collection == null ) Collection = new HashSet < IDictionary < string , object > > ( new DictionaryEqualityComparer ( ) ) ;
111+ Collection . Add ( row ) ;
112+ }
173113
174- public TValue this [ TKey key ]
175- {
176- get { return _super [ key ] ; }
177- set { _super [ key ] = value ; }
114+ public void SetSingle ( IDictionary < string , object > row )
115+ {
116+ Single = row ;
117+ }
178118 }
179119
180- public ICollection < TKey > Keys
120+ private IEnumerable < Tuple < string , Dictionary < string , object > > > ExtractSingleObjects ( IDictionary < string , object > source )
181121 {
182- get { return _super . Keys . Where ( _keyFilter ) . ToList ( ) . AsReadOnly ( ) ; }
183- }
122+ var names =
123+ source . Keys . Where ( k => k . StartsWith ( "__with1__" ) ) . Select (
124+ k => k . Split ( new [ ] { "__" } , StringSplitOptions . RemoveEmptyEntries ) [ 1 ] ) . Distinct ( ) . ToList ( ) ;
184125
185- public ICollection < TValue > Values
186- {
187- get { return Filter ( ) . Select ( kvp => kvp . Value ) . ToList ( ) . AsReadOnly ( ) ; }
126+ return from name in names
127+ let pattern = "__with1__" + name + "__"
128+ select Tuple . Create ( name , source . Where ( kvp => kvp . Key . StartsWith ( pattern ) )
129+ . ToDictionary ( kvp => kvp . Key . Replace ( pattern , "" ) , kvp => kvp . Value , HomogenizedEqualityComparer . DefaultInstance ) ) ;
188130 }
189-
190- public SubDictionary ( IDictionary < TKey , TValue > super , Func < TKey , bool > keyFilter )
131+ private IEnumerable < Tuple < string , Dictionary < string , object > > > ExtractCollectionObjects ( IDictionary < string , object > source )
191132 {
192- _super = super ;
193- _keyFilter = keyFilter ;
194- }
133+ var names =
134+ source . Keys . Where ( k => k . StartsWith ( "__withn__" ) ) . Select (
135+ k => k . Split ( new [ ] { "__" } , StringSplitOptions . RemoveEmptyEntries ) [ 1 ] ) . Distinct ( ) . ToList ( ) ;
195136
196- IEnumerator IEnumerable . GetEnumerator ( )
197- {
198- return GetEnumerator ( ) ;
137+ return from name in names
138+ let pattern = "__withn__" + name + "__"
139+ select Tuple . Create ( name , source . Where ( kvp => kvp . Key . StartsWith ( pattern ) )
140+ . ToDictionary ( kvp => kvp . Key . Replace ( pattern , "" ) , kvp => kvp . Value , HomogenizedEqualityComparer . DefaultInstance ) ) ;
199141 }
200142 }
201143}
0 commit comments