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 }