Mercurial > pub > bltoolkit
comparison Extensions/JointureAddOn/Mapping/FullMappingSchema.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 #region | |
2 | |
3 using System; | |
4 using System.Collections; | |
5 using System.Collections.Generic; | |
6 using System.Data; | |
7 using System.Linq; | |
8 using BLToolkit.Data; | |
9 using BLToolkit.Reflection.Extension; | |
10 | |
11 #endregion | |
12 | |
13 namespace BLToolkit.Mapping | |
14 { | |
15 public class FullMappingSchema : MappingSchema | |
16 { | |
17 #region Fields | |
18 | |
19 private readonly DbManager _db; | |
20 private readonly bool _ignoreLazyLoad; | |
21 private DataTable _schema; | |
22 private List<string> _schemaColumns; | |
23 private readonly MappingSchema _parentMappingSchema; | |
24 private readonly FactoryType _factoryType; | |
25 | |
26 private ExtensionList _extensions; | |
27 | |
28 #endregion | |
29 | |
30 public FullMappingSchema(DbManager db, bool ignoreLazyLoad = false, MappingSchema parentMappingSchema = null, | |
31 FactoryType factoryType = FactoryType.LazyLoading) | |
32 { | |
33 _db = db; | |
34 _parentMappingSchema = parentMappingSchema; | |
35 _factoryType = factoryType; | |
36 _ignoreLazyLoad = ignoreLazyLoad; | |
37 } | |
38 | |
39 #region Overrides | |
40 | |
41 public override ExtensionList Extensions | |
42 { | |
43 get | |
44 { | |
45 if (_parentMappingSchema != null) | |
46 return this._parentMappingSchema.Extensions; | |
47 return _extensions; | |
48 } | |
49 set | |
50 { | |
51 if (_parentMappingSchema != null) | |
52 this._parentMappingSchema.Extensions = value; | |
53 _extensions = value; | |
54 } | |
55 } | |
56 | |
57 protected override ObjectMapper CreateObjectMapperInstance(Type type) | |
58 { | |
59 return new FullObjectMapper(_db, _ignoreLazyLoad,_factoryType); | |
60 } | |
61 | |
62 protected override void MapInternal(Reflection.InitContext initContext, IMapDataSource source, object sourceObject, IMapDataDestination dest, object destObject, params object[] parameters) | |
63 { | |
64 FullObjectMapper mapper = (FullObjectMapper)initContext.ObjectMapper; | |
65 IDataReader dataReader = (IDataReader)sourceObject; | |
66 | |
67 //int[] index = GetIndex(source, dest); | |
68 //IValueMapper[] mappers = GetValueMappers(source, dest, index); | |
69 | |
70 //foreach (var valueMapper in mappers) | |
71 //{ | |
72 | |
73 //} | |
74 | |
75 InitSchema(dataReader); | |
76 | |
77 if (mapper.ColParent) | |
78 { | |
79 FillObject(mapper, dataReader, destObject); | |
80 while (dataReader.Read()) | |
81 { | |
82 destObject = FillObject(destObject, mapper, dataReader); | |
83 } | |
84 } | |
85 else | |
86 FillObject(mapper, dataReader, destObject); | |
87 } | |
88 | |
89 public override IList MapDataReaderToList( | |
90 IDataReader reader, | |
91 IList list, | |
92 Type destObjectType, | |
93 params object[] parameters) | |
94 { | |
95 return internalMapDataReaderToList(reader, list, destObjectType, parameters); | |
96 } | |
97 | |
98 #endregion | |
99 | |
100 #region Private methods | |
101 | |
102 private object FillObject(object result, IObjectMapper mapper, IDataReader datareader) | |
103 { | |
104 foreach (IMapper map in mapper.PropertiesMapping) | |
105 { | |
106 if (map is IObjectMapper && (map as IObjectMapper).IsLazy) | |
107 continue; | |
108 | |
109 if (map is CollectionFullObjectMapper) | |
110 { | |
111 var collectionFullObjectMapper = (CollectionFullObjectMapper) map; | |
112 object listInstance = collectionFullObjectMapper.Getter(result); | |
113 if (listInstance == null) | |
114 { | |
115 listInstance = Activator.CreateInstance((map as CollectionFullObjectMapper).PropertyCollectionType); | |
116 map.Setter(result, listInstance); | |
117 } | |
118 var list = (IList) listInstance; | |
119 object fillObject = ((CollectionFullObjectMapper)map).CreateInstance(); | |
120 FillObject((CollectionFullObjectMapper) map, datareader, fillObject); | |
121 | |
122 if (list.Count > 0) | |
123 { | |
124 var curMapper = (FullObjectMapper)GetObjectMapper(fillObject.GetType()); | |
125 | |
126 object lastElement = list[list.Count - 1]; | |
127 | |
128 bool allPksEqual = true; | |
129 | |
130 //This is needed, because DBValue can be Null, but the Field can be Guid, wich then is filled with Guid.Empty and this is also a valid value! | |
131 /*foreach (var pkIndex in pkIndexes) | |
132 { | |
133 var dbValue = reader.GetValue(pkIndex); | |
134 if (dbValue == DBNull.Value) | |
135 { | |
136 pkIsNull = true; | |
137 break; | |
138 } | |
139 }*/ | |
140 | |
141 foreach (var pkGetter in curMapper.PrimaryKeyValueGetters) | |
142 { | |
143 object lastPk = pkGetter.Invoke(lastElement); | |
144 object currentPk = pkGetter.Invoke(fillObject); | |
145 | |
146 if (!lastPk.Equals(currentPk)) | |
147 { | |
148 allPksEqual = false; | |
149 break; | |
150 } | |
151 } | |
152 | |
153 if (allPksEqual) | |
154 continue; | |
155 } | |
156 | |
157 ((IList) listInstance).Add(fillObject); | |
158 } | |
159 } | |
160 | |
161 return result; | |
162 } | |
163 | |
164 private void FillObject(IObjectMapper mapper, IDataReader datareader, object result) | |
165 { | |
166 foreach (IMapper map in mapper.PropertiesMapping) | |
167 { | |
168 if (map is IObjectMapper && (map as IObjectMapper).IsLazy) | |
169 continue; | |
170 | |
171 if (map is ValueMapper) | |
172 { | |
173 if (((ValueMapper)map).SetDataReaderIndex(_schemaColumns)) | |
174 continue; | |
175 } | |
176 | |
177 if (datareader.IsDBNull(map.DataReaderIndex)) | |
178 continue; | |
179 | |
180 if (map is ValueMapper) | |
181 { | |
182 object value = datareader.GetValue(map.DataReaderIndex); | |
183 | |
184 try | |
185 { | |
186 map.Setter(result, value); | |
187 } | |
188 catch (Exception exception) | |
189 { | |
190 throw new Exception( | |
191 string.Format("FillOject failed for field : {0} of class: {1}.\nColumn name : {2} Db type is: {3} and value : {4}", | |
192 map.PropertyName, mapper.PropertyType, | |
193 ((ValueMapper) map).ColumnName, | |
194 value == null ? "Null" : value.GetType().ToString(), value), exception); | |
195 } | |
196 } | |
197 | |
198 if (map is FullObjectMapper) | |
199 { | |
200 object fillObject = ((FullObjectMapper) map).CreateInstance(); | |
201 FillObject((FullObjectMapper) map, datareader, fillObject); | |
202 map.Setter(result, fillObject); | |
203 } | |
204 | |
205 if (map is CollectionFullObjectMapper) | |
206 { | |
207 var collectionFullObjectMapper = (CollectionFullObjectMapper) map; | |
208 | |
209 object listInstance = collectionFullObjectMapper.Getter(result); | |
210 if (listInstance == null) | |
211 { | |
212 listInstance = Activator.CreateInstance((map as CollectionFullObjectMapper).PropertyCollectionType); | |
213 map.Setter(result, listInstance); | |
214 } | |
215 | |
216 object fillObject = ((CollectionFullObjectMapper)map).CreateInstance(); | |
217 FillObject((CollectionFullObjectMapper) map, datareader, fillObject); | |
218 ((IList) listInstance).Add(fillObject); | |
219 } | |
220 } | |
221 } | |
222 | |
223 private void InitSchema(IDataReader reader) | |
224 { | |
225 _schemaColumns = new List<string>(); | |
226 _schema = reader.GetSchemaTable(); | |
227 if (_schema != null) | |
228 _schema.Rows.Cast<DataRow>().ToList().ForEach(dr => _schemaColumns.Add((string)dr["ColumnName"])); | |
229 } | |
230 | |
231 private IList internalMapDataReaderToList( | |
232 IDataReader reader, | |
233 IList list, | |
234 Type destObjectType, | |
235 params object[] parameters) | |
236 { | |
237 FullObjectMapper mapper = (FullObjectMapper)GetObjectMapper(destObjectType); | |
238 | |
239 InitSchema(reader); | |
240 | |
241 object currentItem = null; | |
242 | |
243 List<int> pkIndexes = new List<int>(); | |
244 foreach (var nm in mapper.PrimaryKeyNames) | |
245 { | |
246 pkIndexes.Add(mapper.PropertiesMapping.First(x => x.PropertyName == nm).DataReaderIndex); | |
247 } | |
248 | |
249 while (reader.Read()) | |
250 { | |
251 var result = mapper.CreateInstance(); | |
252 | |
253 FillObject(mapper, reader, result); | |
254 if (currentItem == null) | |
255 { | |
256 currentItem = result; | |
257 list.Add(result); | |
258 continue; | |
259 } | |
260 | |
261 bool pkIsNull = false; | |
262 bool allPksEqual = true; | |
263 | |
264 //This is needed, because DBValue can be Null, but the Field can be Guid, wich then is filled with Guid.Empty and this is also a valid value! | |
265 foreach (var pkIndex in pkIndexes) | |
266 { | |
267 var dbValue = reader.GetValue(pkIndex); | |
268 if (dbValue == DBNull.Value) | |
269 { | |
270 pkIsNull = true; | |
271 break; | |
272 } | |
273 } | |
274 | |
275 if (!pkIsNull) | |
276 foreach (var pkGetter in mapper.PrimaryKeyValueGetters) | |
277 { | |
278 object resultPk = pkGetter.Invoke(result); | |
279 object currentItemPk = pkGetter.Invoke(currentItem); | |
280 | |
281 if (!resultPk.Equals(currentItemPk)) | |
282 { | |
283 allPksEqual = false; | |
284 break; | |
285 } | |
286 } | |
287 | |
288 if (!pkIsNull && !allPksEqual) | |
289 { | |
290 currentItem = result; | |
291 list.Add(result); | |
292 //continue; | |
293 } | |
294 | |
295 if (mapper.ColParent) | |
296 { | |
297 FillObject(currentItem, mapper, reader); | |
298 } | |
299 } | |
300 | |
301 return list; | |
302 } | |
303 | |
304 #endregion | |
305 } | |
306 } |