PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/Source/Mapping/MappingSchema.cs

https://gitlab.com/Chermyanin/bltoolkitsourcelearn
C# | 3854 lines | 3007 code | 812 blank | 35 comment | 498 complexity | d901190d2cd114a8961639a97c686c11 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.Linq;
  6. using System.Data.SqlTypes;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.IO;
  10. using System.Reflection;
  11. using System.Diagnostics.CodeAnalysis;
  12. using System.Threading;
  13. using System.Xml;
  14. #if !SILVERLIGHT
  15. using System.Xml.Linq;
  16. #endif
  17. using BLToolkit.Common;
  18. using BLToolkit.Properties;
  19. using BLToolkit.Reflection;
  20. using BLToolkit.Reflection.Extension;
  21. using BLToolkit.Reflection.MetadataProvider;
  22. #region ReSharper disable
  23. // ReSharper disable SuggestUseVarKeywordEvident
  24. // ReSharper disable UseObjectOrCollectionInitializer
  25. // ReSharper disable SuggestUseVarKeywordEverywhere
  26. // ReSharper disable RedundantTypeArgumentsOfMethod
  27. #endregion
  28. using KeyValue = System.Collections.Generic.KeyValuePair<System.Type,System.Type>;
  29. using Convert = BLToolkit.Common.Convert;
  30. namespace BLToolkit.Mapping
  31. {
  32. public class MappingSchema
  33. {
  34. #region Constructors
  35. public MappingSchema()
  36. {
  37. InitNullValues();
  38. }
  39. #endregion
  40. #region ObjectMapper Support
  41. private readonly Dictionary<Type,ObjectMapper> _mappers = new Dictionary<Type,ObjectMapper>();
  42. private readonly Dictionary<Type,ObjectMapper> _pendingMappers = new Dictionary<Type,ObjectMapper>();
  43. public ObjectMapper GetObjectMapper(Type type)
  44. {
  45. ObjectMapper om;
  46. lock (_mappers)
  47. {
  48. if (_mappers.TryGetValue(type, out om))
  49. return om;
  50. // This object mapper is initializing right now.
  51. // Note that only one thread can access to _pendingMappers each time.
  52. //
  53. if (_pendingMappers.TryGetValue(type, out om))
  54. return om;
  55. om = CreateObjectMapper(type);
  56. if (om == null)
  57. throw new MappingException(
  58. string.Format("Cannot create object mapper for the '{0}' type.", type.FullName));
  59. _pendingMappers.Add(type, om);
  60. try
  61. {
  62. om.Init(this, type);
  63. }
  64. finally
  65. {
  66. _pendingMappers.Remove(type);
  67. }
  68. // Officially publish this ready to use object mapper.
  69. //
  70. SetObjectMapperInternal(type, om);
  71. return om;
  72. }
  73. }
  74. private void SetObjectMapperInternal(Type type, ObjectMapper om)
  75. {
  76. _mappers.Add(type, om);
  77. if (type.IsAbstract)
  78. {
  79. var actualType = TypeAccessor.GetAccessor(type).Type;
  80. if (!_mappers.ContainsKey(actualType))
  81. _mappers.Add(actualType, om);
  82. }
  83. }
  84. public void SetObjectMapper(Type type, ObjectMapper om)
  85. {
  86. if (type == null) throw new ArgumentNullException("type");
  87. lock (_mappers)
  88. SetObjectMapperInternal(type, om);
  89. }
  90. protected virtual ObjectMapper CreateObjectMapper(Type type)
  91. {
  92. Attribute attr = TypeHelper.GetFirstAttribute(type, typeof(ObjectMapperAttribute));
  93. return attr == null? CreateObjectMapperInstance(type): ((ObjectMapperAttribute)attr).ObjectMapper;
  94. }
  95. protected virtual ObjectMapper CreateObjectMapperInstance(Type type)
  96. {
  97. return new ObjectMapper();
  98. }
  99. #endregion
  100. #region MetadataProvider
  101. private MetadataProviderBase _metadataProvider;
  102. public MetadataProviderBase MetadataProvider
  103. {
  104. [DebuggerStepThrough]
  105. get { return _metadataProvider ?? (_metadataProvider = CreateMetadataProvider()); }
  106. set { _metadataProvider = value; }
  107. }
  108. protected virtual MetadataProviderBase CreateMetadataProvider()
  109. {
  110. return MetadataProviderBase.CreateProvider();
  111. }
  112. #endregion
  113. #region Public Members
  114. public virtual ExtensionList Extensions { get; set; }
  115. #endregion
  116. #region Convert
  117. public virtual void InitNullValues()
  118. {
  119. DefaultSByteNullValue = (SByte) GetNullValue(typeof(SByte));
  120. DefaultInt16NullValue = (Int16) GetNullValue(typeof(Int16));
  121. DefaultInt32NullValue = (Int32) GetNullValue(typeof(Int32));
  122. DefaultInt64NullValue = (Int64) GetNullValue(typeof(Int64));
  123. DefaultByteNullValue = (Byte) GetNullValue(typeof(Byte));
  124. DefaultUInt16NullValue = (UInt16) GetNullValue(typeof(UInt16));
  125. DefaultUInt32NullValue = (UInt32) GetNullValue(typeof(UInt32));
  126. DefaultUInt64NullValue = (UInt64) GetNullValue(typeof(UInt64));
  127. DefaultCharNullValue = (Char) GetNullValue(typeof(Char));
  128. DefaultSingleNullValue = (Single) GetNullValue(typeof(Single));
  129. DefaultDoubleNullValue = (Double) GetNullValue(typeof(Double));
  130. DefaultBooleanNullValue = (Boolean) GetNullValue(typeof(Boolean));
  131. DefaultStringNullValue = (String) GetNullValue(typeof(String));
  132. DefaultDateTimeNullValue = (DateTime) GetNullValue(typeof(DateTime));
  133. DefaultDateTimeOffsetNullValue = (DateTimeOffset)GetNullValue(typeof(DateTimeOffset));
  134. DefaultLinqBinaryNullValue = (Binary) GetNullValue(typeof(Binary));
  135. DefaultDecimalNullValue = (Decimal) GetNullValue(typeof(Decimal));
  136. DefaultGuidNullValue = (Guid) GetNullValue(typeof(Guid));
  137. DefaultStreamNullValue = (Stream) GetNullValue(typeof(Stream));
  138. #if !SILVERLIGHT
  139. DefaultXmlReaderNullValue = (XmlReader) GetNullValue(typeof(XmlReader));
  140. DefaultXmlDocumentNullValue = (XmlDocument) GetNullValue(typeof(XmlDocument));
  141. DefaultXElementNullValue = (XElement) GetNullValue(typeof(XElement));
  142. #endif
  143. }
  144. #region Primitive Types
  145. [CLSCompliant(false)]
  146. public sbyte DefaultSByteNullValue { get; set; }
  147. [CLSCompliant(false)]
  148. public virtual SByte ConvertToSByte(object value)
  149. {
  150. return
  151. value is SByte ? (SByte)value :
  152. value is Byte ? (SByte)(Byte)value :
  153. value == null ? DefaultSByteNullValue :
  154. Convert.ToSByte(value);
  155. }
  156. public short DefaultInt16NullValue { get; set; }
  157. public virtual Int16 ConvertToInt16(object value)
  158. {
  159. return
  160. value is Int16? (Int16)value:
  161. value == null || value is DBNull? DefaultInt16NullValue:
  162. Convert.ToInt16(value);
  163. }
  164. public int DefaultInt32NullValue { get; set; }
  165. public virtual Int32 ConvertToInt32(object value)
  166. {
  167. return
  168. value is Int32? (Int32)value:
  169. value == null || value is DBNull? DefaultInt32NullValue:
  170. Convert.ToInt32(value);
  171. }
  172. public long DefaultInt64NullValue { get; set; }
  173. public virtual Int64 ConvertToInt64(object value)
  174. {
  175. return
  176. value is Int64? (Int64)value:
  177. value == null || value is DBNull? DefaultInt64NullValue:
  178. Convert.ToInt64(value);
  179. }
  180. public byte DefaultByteNullValue { get; set; }
  181. public virtual Byte ConvertToByte(object value)
  182. {
  183. return
  184. value is Byte? (Byte)value:
  185. value == null || value is DBNull? DefaultByteNullValue:
  186. Convert.ToByte(value);
  187. }
  188. [CLSCompliant(false)]
  189. public ushort DefaultUInt16NullValue { get; set; }
  190. [CLSCompliant(false)]
  191. public virtual UInt16 ConvertToUInt16(object value)
  192. {
  193. return
  194. value is UInt16? (UInt16)value:
  195. value is Int16? (UInt16)(Int16)value:
  196. value == null || value is DBNull? DefaultUInt16NullValue:
  197. Convert.ToUInt16(value);
  198. }
  199. [CLSCompliant(false)]
  200. public uint DefaultUInt32NullValue { get; set; }
  201. [CLSCompliant(false)]
  202. public virtual UInt32 ConvertToUInt32(object value)
  203. {
  204. return
  205. value is UInt32? (UInt32)value:
  206. value is Int32? (UInt32)(Int32)value:
  207. value == null || value is DBNull? DefaultUInt32NullValue:
  208. Convert.ToUInt32(value);
  209. }
  210. [CLSCompliant(false)]
  211. public ulong DefaultUInt64NullValue { get; set; }
  212. [CLSCompliant(false)]
  213. public virtual UInt64 ConvertToUInt64(object value)
  214. {
  215. return
  216. value is UInt64? (UInt64)value:
  217. value is Int64? (UInt64)(Int64)value:
  218. value == null || value is DBNull? DefaultUInt64NullValue:
  219. Convert.ToUInt64(value);
  220. }
  221. public char DefaultCharNullValue { get; set; }
  222. public virtual Char ConvertToChar(object value)
  223. {
  224. return
  225. value is Char? (Char)value:
  226. value == null || value is DBNull? DefaultCharNullValue:
  227. Convert.ToChar(value);
  228. }
  229. public float DefaultSingleNullValue { get; set; }
  230. public virtual Single ConvertToSingle(object value)
  231. {
  232. return
  233. value is Single? (Single)value:
  234. value == null || value is DBNull? DefaultSingleNullValue:
  235. Convert.ToSingle(value);
  236. }
  237. public double DefaultDoubleNullValue { get; set; }
  238. public virtual Double ConvertToDouble(object value)
  239. {
  240. return
  241. value is Double? (Double)value:
  242. value == null || value is DBNull? DefaultDoubleNullValue:
  243. Convert.ToDouble(value);
  244. }
  245. public bool DefaultBooleanNullValue { get; set; }
  246. public virtual Boolean ConvertToBoolean(object value)
  247. {
  248. return
  249. value is Boolean? (Boolean)value:
  250. value == null || value is DBNull? DefaultBooleanNullValue:
  251. Convert.ToBoolean(value);
  252. }
  253. #endregion
  254. #region Simple Types
  255. public string DefaultStringNullValue { get; set; }
  256. public virtual String ConvertToString(object value)
  257. {
  258. return
  259. value is String? (String)value :
  260. value == null || value is DBNull? DefaultStringNullValue:
  261. Convert.ToString(value);
  262. }
  263. public DateTime DefaultDateTimeNullValue { get; set; }
  264. public virtual DateTime ConvertToDateTime(object value)
  265. {
  266. return
  267. value is DateTime? (DateTime)value:
  268. value == null || value is DBNull? DefaultDateTimeNullValue:
  269. Convert.ToDateTime(value);
  270. }
  271. public virtual TimeSpan ConvertToTimeSpan(object value)
  272. {
  273. return ConvertToDateTime(value).TimeOfDay;
  274. }
  275. public DateTimeOffset DefaultDateTimeOffsetNullValue { get; set; }
  276. public virtual DateTimeOffset ConvertToDateTimeOffset(object value)
  277. {
  278. return
  279. value is DateTimeOffset? (DateTimeOffset)value:
  280. value == null || value is DBNull? DefaultDateTimeOffsetNullValue:
  281. Convert.ToDateTimeOffset(value);
  282. }
  283. public Binary DefaultLinqBinaryNullValue { get; set; }
  284. public virtual Binary ConvertToLinqBinary(object value)
  285. {
  286. return
  287. value is Binary ? (Binary)value:
  288. value is byte[] ? new Binary((byte[])value) :
  289. value == null || value is DBNull? DefaultLinqBinaryNullValue:
  290. Convert.ToLinqBinary(value);
  291. }
  292. public decimal DefaultDecimalNullValue { get; set; }
  293. public virtual Decimal ConvertToDecimal(object value)
  294. {
  295. return
  296. value is Decimal? (Decimal)value:
  297. value == null || value is DBNull? DefaultDecimalNullValue:
  298. Convert.ToDecimal(value);
  299. }
  300. public Guid DefaultGuidNullValue { get; set; }
  301. public virtual Guid ConvertToGuid(object value)
  302. {
  303. return
  304. value is Guid? (Guid)value:
  305. value == null || value is DBNull? DefaultGuidNullValue:
  306. Convert.ToGuid(value);
  307. }
  308. public Stream DefaultStreamNullValue { get; set; }
  309. public virtual Stream ConvertToStream(object value)
  310. {
  311. return
  312. value is Stream? (Stream)value:
  313. value == null || value is DBNull? DefaultStreamNullValue:
  314. Convert.ToStream(value);
  315. }
  316. #if !SILVERLIGHT
  317. public XmlReader DefaultXmlReaderNullValue { get; set; }
  318. public virtual XmlReader ConvertToXmlReader(object value)
  319. {
  320. return
  321. value is XmlReader? (XmlReader)value:
  322. value == null || value is DBNull? DefaultXmlReaderNullValue:
  323. Convert.ToXmlReader(value);
  324. }
  325. public XmlDocument DefaultXmlDocumentNullValue { get; set; }
  326. public virtual XmlDocument ConvertToXmlDocument(object value)
  327. {
  328. return
  329. value is XmlDocument? (XmlDocument)value:
  330. value == null || value is DBNull? DefaultXmlDocumentNullValue:
  331. Convert.ToXmlDocument(value);
  332. }
  333. public XElement DefaultXElementNullValue { get; set; }
  334. public virtual XElement ConvertToXElement(object value)
  335. {
  336. return
  337. value is XElement ? (XElement)value :
  338. value == null || value is DBNull ? DefaultXElementNullValue :
  339. XElement.Parse(value.ToString());
  340. }
  341. #endif
  342. public virtual byte[] ConvertToByteArray(object value)
  343. {
  344. return
  345. value is byte[]? (byte[])value:
  346. value == null || value is DBNull? null:
  347. Convert.ToByteArray(value);
  348. }
  349. public virtual char[] ConvertToCharArray(object value)
  350. {
  351. return
  352. value is char[]? (char[])value:
  353. value == null || value is DBNull? null:
  354. Convert.ToCharArray(value);
  355. }
  356. #endregion
  357. #region Nullable Types
  358. [CLSCompliant(false)]
  359. public virtual SByte? ConvertToNullableSByte(object value)
  360. {
  361. return
  362. value is SByte? (SByte?)value:
  363. value is Byte? (SByte?)(Byte)value:
  364. value == null || value is DBNull? null:
  365. Convert.ToNullableSByte(value);
  366. }
  367. public virtual Int16? ConvertToNullableInt16(object value)
  368. {
  369. return
  370. value is Int16? (Int16?)value:
  371. value == null || value is DBNull? null:
  372. Convert.ToNullableInt16(value);
  373. }
  374. public virtual Int32? ConvertToNullableInt32(object value)
  375. {
  376. return
  377. value is Int32? (Int32?)value:
  378. value == null || value is DBNull? null:
  379. Convert.ToNullableInt32(value);
  380. }
  381. public virtual Int64? ConvertToNullableInt64(object value)
  382. {
  383. return
  384. value is Int64? (Int64?)value:
  385. value == null || value is DBNull? null:
  386. Convert.ToNullableInt64(value);
  387. }
  388. public virtual Byte? ConvertToNullableByte(object value)
  389. {
  390. return
  391. value is Byte? (Byte?)value:
  392. value == null || value is DBNull? null:
  393. Convert.ToNullableByte(value);
  394. }
  395. [CLSCompliant(false)]
  396. public virtual UInt16? ConvertToNullableUInt16(object value)
  397. {
  398. return
  399. value is UInt16? (UInt16?)value:
  400. value is Int16? (UInt16?)(Int16)value:
  401. value == null || value is DBNull? null:
  402. Convert.ToNullableUInt16(value);
  403. }
  404. [CLSCompliant(false)]
  405. public virtual UInt32? ConvertToNullableUInt32(object value)
  406. {
  407. return
  408. value is UInt32? (UInt32?)value:
  409. value is Int32? (UInt32?)(Int32)value:
  410. value == null || value is DBNull? null:
  411. Convert.ToNullableUInt32(value);
  412. }
  413. [CLSCompliant(false)]
  414. public virtual UInt64? ConvertToNullableUInt64(object value)
  415. {
  416. return
  417. value is UInt64? (UInt64?)value:
  418. value is Int64? (UInt64?)(Int64)value:
  419. value == null || value is DBNull? null:
  420. Convert.ToNullableUInt64(value);
  421. }
  422. public virtual Char? ConvertToNullableChar(object value)
  423. {
  424. return
  425. value is Char? (Char?)value:
  426. value == null || value is DBNull? null:
  427. Convert.ToNullableChar(value);
  428. }
  429. public virtual Double? ConvertToNullableDouble(object value)
  430. {
  431. return
  432. value is Double? (Double?)value:
  433. value == null || value is DBNull? null:
  434. Convert.ToNullableDouble(value);
  435. }
  436. public virtual Single? ConvertToNullableSingle(object value)
  437. {
  438. return
  439. value is Single? (Single?)value:
  440. value == null || value is DBNull? null:
  441. Convert.ToNullableSingle(value);
  442. }
  443. public virtual Boolean? ConvertToNullableBoolean(object value)
  444. {
  445. return
  446. value is Boolean? (Boolean?)value:
  447. value == null || value is DBNull? null:
  448. Convert.ToNullableBoolean(value);
  449. }
  450. public virtual DateTime? ConvertToNullableDateTime(object value)
  451. {
  452. return
  453. value is DateTime? (DateTime?)value:
  454. value == null || value is DBNull? null:
  455. Convert.ToNullableDateTime(value);
  456. }
  457. public virtual TimeSpan? ConvertToNullableTimeSpan(object value)
  458. {
  459. DateTime? dt = ConvertToNullableDateTime(value);
  460. return dt == null? null : (TimeSpan?)dt.Value.TimeOfDay;
  461. }
  462. public virtual DateTimeOffset? ConvertToNullableDateTimeOffset(object value)
  463. {
  464. return
  465. value is DateTimeOffset? (DateTimeOffset?)value:
  466. value == null || value is DBNull? null:
  467. Convert.ToNullableDateTimeOffset(value);
  468. }
  469. public virtual Decimal? ConvertToNullableDecimal(object value)
  470. {
  471. return
  472. value is Decimal? (Decimal?)value:
  473. value == null || value is DBNull? null:
  474. Convert.ToNullableDecimal(value);
  475. }
  476. public virtual Guid? ConvertToNullableGuid(object value)
  477. {
  478. return
  479. value is Guid? (Guid?)value:
  480. value == null || value is DBNull? null:
  481. Convert.ToNullableGuid(value);
  482. }
  483. #endregion
  484. #region SqlTypes
  485. #if !SILVERLIGHT
  486. public virtual SqlByte ConvertToSqlByte(object value)
  487. {
  488. return
  489. value == null || value is DBNull? SqlByte.Null :
  490. value is SqlByte? (SqlByte)value:
  491. Convert.ToSqlByte(value);
  492. }
  493. public virtual SqlInt16 ConvertToSqlInt16(object value)
  494. {
  495. return
  496. value == null || value is DBNull? SqlInt16.Null:
  497. value is SqlInt16? (SqlInt16)value:
  498. Convert.ToSqlInt16(value);
  499. }
  500. public virtual SqlInt32 ConvertToSqlInt32(object value)
  501. {
  502. return
  503. value == null || value is DBNull? SqlInt32.Null:
  504. value is SqlInt32? (SqlInt32)value:
  505. Convert.ToSqlInt32(value);
  506. }
  507. public virtual SqlInt64 ConvertToSqlInt64(object value)
  508. {
  509. return
  510. value == null || value is DBNull? SqlInt64.Null:
  511. value is SqlInt64? (SqlInt64)value:
  512. Convert.ToSqlInt64(value);
  513. }
  514. public virtual SqlSingle ConvertToSqlSingle(object value)
  515. {
  516. return
  517. value == null || value is DBNull? SqlSingle.Null:
  518. value is SqlSingle? (SqlSingle)value:
  519. Convert.ToSqlSingle(value);
  520. }
  521. public virtual SqlBoolean ConvertToSqlBoolean(object value)
  522. {
  523. return
  524. value == null || value is DBNull? SqlBoolean.Null:
  525. value is SqlBoolean? (SqlBoolean)value:
  526. Convert.ToSqlBoolean(value);
  527. }
  528. public virtual SqlDouble ConvertToSqlDouble(object value)
  529. {
  530. return
  531. value == null || value is DBNull? SqlDouble.Null:
  532. value is SqlDouble? (SqlDouble)value:
  533. Convert.ToSqlDouble(value);
  534. }
  535. public virtual SqlDateTime ConvertToSqlDateTime(object value)
  536. {
  537. return
  538. value == null || value is DBNull? SqlDateTime.Null:
  539. value is SqlDateTime? (SqlDateTime)value:
  540. Convert.ToSqlDateTime(value);
  541. }
  542. public virtual SqlDecimal ConvertToSqlDecimal(object value)
  543. {
  544. return
  545. value == null || value is DBNull? SqlDecimal.Null:
  546. value is SqlDecimal? (SqlDecimal)value:
  547. value is SqlMoney? ((SqlMoney)value).ToSqlDecimal():
  548. Convert.ToSqlDecimal(value);
  549. }
  550. public virtual SqlMoney ConvertToSqlMoney(object value)
  551. {
  552. return
  553. value == null || value is DBNull? SqlMoney.Null:
  554. value is SqlMoney? (SqlMoney)value:
  555. value is SqlDecimal? ((SqlDecimal)value).ToSqlMoney():
  556. Convert.ToSqlMoney(value);
  557. }
  558. public virtual SqlString ConvertToSqlString(object value)
  559. {
  560. return
  561. value == null || value is DBNull? SqlString.Null:
  562. value is SqlString? (SqlString)value:
  563. Convert.ToSqlString(value);
  564. }
  565. public virtual SqlBinary ConvertToSqlBinary(object value)
  566. {
  567. return
  568. value == null || value is DBNull? SqlBinary.Null:
  569. value is SqlBinary? (SqlBinary)value:
  570. Convert.ToSqlBinary(value);
  571. }
  572. public virtual SqlGuid ConvertToSqlGuid(object value)
  573. {
  574. return
  575. value == null || value is DBNull? SqlGuid.Null:
  576. value is SqlGuid? (SqlGuid)value:
  577. Convert.ToSqlGuid(value);
  578. }
  579. public virtual SqlBytes ConvertToSqlBytes(object value)
  580. {
  581. return
  582. value == null || value is DBNull? SqlBytes.Null:
  583. value is SqlBytes? (SqlBytes)value:
  584. Convert.ToSqlBytes(value);
  585. }
  586. public virtual SqlChars ConvertToSqlChars(object value)
  587. {
  588. return
  589. value == null || value is DBNull? SqlChars.Null:
  590. value is SqlChars? (SqlChars)value:
  591. Convert.ToSqlChars(value);
  592. }
  593. public virtual SqlXml ConvertToSqlXml(object value)
  594. {
  595. return
  596. value == null || value is DBNull? SqlXml.Null:
  597. value is SqlXml? (SqlXml)value:
  598. Convert.ToSqlXml(value);
  599. }
  600. #endif
  601. #endregion
  602. #region General case
  603. public virtual T GetDefaultNullValue<T>()
  604. {
  605. switch (Type.GetTypeCode(typeof(T)))
  606. {
  607. case TypeCode.Boolean: return (T)(object)DefaultBooleanNullValue;
  608. case TypeCode.Byte: return (T)(object)DefaultByteNullValue;
  609. case TypeCode.Char: return (T)(object)DefaultCharNullValue;
  610. case TypeCode.DateTime: return (T)(object)DefaultDateTimeNullValue;
  611. case TypeCode.Decimal: return (T)(object)DefaultDecimalNullValue;
  612. case TypeCode.Double: return (T)(object)DefaultDoubleNullValue;
  613. case TypeCode.Int16: return (T)(object)DefaultInt16NullValue;
  614. case TypeCode.Int32: return (T)(object)DefaultInt32NullValue;
  615. case TypeCode.Int64: return (T)(object)DefaultInt64NullValue;
  616. case TypeCode.SByte: return (T)(object)DefaultSByteNullValue;
  617. case TypeCode.Single: return (T)(object)DefaultSingleNullValue;
  618. case TypeCode.String: return (T)(object)DefaultStringNullValue;
  619. case TypeCode.UInt16: return (T)(object)DefaultUInt16NullValue;
  620. case TypeCode.UInt32: return (T)(object)DefaultUInt32NullValue;
  621. case TypeCode.UInt64: return (T)(object)DefaultUInt64NullValue;
  622. }
  623. if (typeof(Guid) == typeof(T)) return (T)(object)DefaultGuidNullValue;
  624. if (typeof(Stream) == typeof(T)) return (T)(object)DefaultStreamNullValue;
  625. #if !SILVERLIGHT
  626. if (typeof(XmlReader) == typeof(T)) return (T)(object)DefaultXmlReaderNullValue;
  627. if (typeof(XmlDocument) == typeof(T)) return (T)(object)DefaultXmlDocumentNullValue;
  628. if (typeof(XElement) == typeof(T)) return (T)(object)DefaultXElementNullValue;
  629. #endif
  630. if (typeof(DateTimeOffset) == typeof(T)) return (T)(object)DefaultDateTimeOffsetNullValue;
  631. return default(T);
  632. }
  633. public virtual T ConvertTo<T,TP>(TP value)
  634. {
  635. return Equals(value, default(TP))?
  636. GetDefaultNullValue<T>():
  637. Convert<T,TP>.From(value);
  638. }
  639. public virtual object ConvertChangeType(object value, Type conversionType)
  640. {
  641. return ConvertChangeType(value, conversionType, TypeHelper.IsNullable(conversionType));
  642. }
  643. public virtual object ConvertChangeType(object value, Type conversionType, bool isNullable)
  644. {
  645. if (conversionType.IsArray)
  646. {
  647. if (null == value)
  648. return null;
  649. Type srcType = value.GetType();
  650. if (srcType == conversionType)
  651. return value;
  652. if (srcType.IsArray)
  653. {
  654. Type srcElementType = srcType.GetElementType();
  655. Type dstElementType = conversionType.GetElementType();
  656. if (srcElementType.IsArray != dstElementType.IsArray
  657. || (srcElementType.IsArray &&
  658. srcElementType.GetArrayRank() != dstElementType.GetArrayRank()))
  659. {
  660. throw new InvalidCastException(string.Format(
  661. Resources.MappingSchema_IncompatibleArrayTypes,
  662. srcType.FullName, conversionType.FullName));
  663. }
  664. Array srcArray = (Array)value;
  665. Array dstArray;
  666. int rank = srcArray.Rank;
  667. if (rank == 1 && 0 == srcArray.GetLowerBound(0))
  668. {
  669. int arrayLength = srcArray.Length;
  670. dstArray = Array.CreateInstance(dstElementType, arrayLength);
  671. // Int32 is assignable from UInt32, SByte from Byte and so on.
  672. //
  673. if (dstElementType.IsAssignableFrom(srcElementType))
  674. Array.Copy(srcArray, dstArray, arrayLength);
  675. else
  676. for (int i = 0; i < arrayLength; ++i)
  677. dstArray.SetValue(ConvertChangeType(srcArray.GetValue(i), dstElementType, isNullable), i);
  678. }
  679. else
  680. {
  681. #if SILVERLIGHT
  682. throw new InvalidOperationException();
  683. #else
  684. var arrayLength = 1;
  685. var dimensions = new int[rank];
  686. var indices = new int[rank];
  687. var lbounds = new int[rank];
  688. for (int i = 0; i < rank; ++i)
  689. {
  690. arrayLength *= (dimensions[i] = srcArray.GetLength(i));
  691. lbounds[i] = srcArray.GetLowerBound(i);
  692. }
  693. dstArray = Array.CreateInstance(dstElementType, dimensions, lbounds);
  694. for (int i = 0; i < arrayLength; ++i)
  695. {
  696. var index = i;
  697. for (var j = rank - 1; j >= 0; --j)
  698. {
  699. indices[j] = index % dimensions[j] + lbounds[j];
  700. index /= dimensions[j];
  701. }
  702. dstArray.SetValue(ConvertChangeType(srcArray.GetValue(indices), dstElementType, isNullable), indices);
  703. }
  704. #endif
  705. }
  706. return dstArray;
  707. }
  708. }
  709. else if (conversionType.IsEnum)
  710. return Enum.ToObject(conversionType, ConvertChangeType(value, Enum.GetUnderlyingType(conversionType), false));
  711. if (isNullable)
  712. {
  713. if (TypeHelper.IsNullable(conversionType))
  714. {
  715. // Return a null reference or boxed not null value.
  716. //
  717. return value == null || value is DBNull? null:
  718. ConvertChangeType(value, conversionType.GetGenericArguments()[0]);
  719. }
  720. Type type = conversionType.IsEnum? Enum.GetUnderlyingType(conversionType): conversionType;
  721. switch (Type.GetTypeCode(type))
  722. {
  723. case TypeCode.Boolean: return ConvertToNullableBoolean (value);
  724. case TypeCode.Byte: return ConvertToNullableByte (value);
  725. case TypeCode.Char: return ConvertToNullableChar (value);
  726. case TypeCode.DateTime: return ConvertToNullableDateTime(value);
  727. case TypeCode.Decimal: return ConvertToNullableDecimal (value);
  728. case TypeCode.Double: return ConvertToNullableDouble (value);
  729. case TypeCode.Int16: return ConvertToNullableInt16 (value);
  730. case TypeCode.Int32: return ConvertToNullableInt32 (value);
  731. case TypeCode.Int64: return ConvertToNullableInt64 (value);
  732. case TypeCode.SByte: return ConvertToNullableSByte (value);
  733. case TypeCode.Single: return ConvertToNullableSingle (value);
  734. case TypeCode.UInt16: return ConvertToNullableUInt16 (value);
  735. case TypeCode.UInt32: return ConvertToNullableUInt32 (value);
  736. case TypeCode.UInt64: return ConvertToNullableUInt64 (value);
  737. }
  738. if (typeof(Guid) == conversionType) return ConvertToNullableGuid(value);
  739. if (typeof(DateTimeOffset) == conversionType) return ConvertToNullableDateTimeOffset(value);
  740. if (typeof(TimeSpan) == conversionType) return ConvertToNullableTimeSpan(value);
  741. }
  742. switch (Type.GetTypeCode(conversionType))
  743. {
  744. case TypeCode.Boolean: return ConvertToBoolean (value);
  745. case TypeCode.Byte: return ConvertToByte (value);
  746. case TypeCode.Char: return ConvertToChar (value);
  747. case TypeCode.DateTime: return ConvertToDateTime(value);
  748. case TypeCode.Decimal: return ConvertToDecimal (value);
  749. case TypeCode.Double: return ConvertToDouble (value);
  750. case TypeCode.Int16: return ConvertToInt16 (value);
  751. case TypeCode.Int32: return ConvertToInt32 (value);
  752. case TypeCode.Int64: return ConvertToInt64 (value);
  753. case TypeCode.SByte: return ConvertToSByte (value);
  754. case TypeCode.Single: return ConvertToSingle (value);
  755. case TypeCode.String: return ConvertToString (value);
  756. case TypeCode.UInt16: return ConvertToUInt16 (value);
  757. case TypeCode.UInt32: return ConvertToUInt32 (value);
  758. case TypeCode.UInt64: return ConvertToUInt64 (value);
  759. }
  760. if (typeof(Guid) == conversionType) return ConvertToGuid (value);
  761. if (typeof(Stream) == conversionType) return ConvertToStream (value);
  762. #if !SILVERLIGHT
  763. if (typeof(XmlReader) == conversionType) return ConvertToXmlReader (value);
  764. if (typeof(XmlDocument) == conversionType) return ConvertToXmlDocument (value);
  765. if (typeof(XElement) == conversionType) return ConvertToXElement (value);
  766. #endif
  767. if (typeof(byte[]) == conversionType) return ConvertToByteArray (value);
  768. if (typeof(Binary) == conversionType) return ConvertToLinqBinary (value);
  769. if (typeof(DateTimeOffset) == conversionType) return ConvertToDateTimeOffset(value);
  770. if (typeof(char[]) == conversionType) return ConvertToCharArray (value);
  771. if (typeof(TimeSpan) == conversionType) return ConvertToTimeSpan (value);
  772. #if !SILVERLIGHT
  773. if (typeof(SqlInt32) == conversionType) return ConvertToSqlInt32 (value);
  774. if (typeof(SqlString) == conversionType) return ConvertToSqlString (value);
  775. if (typeof(SqlDecimal) == conversionType) return ConvertToSqlDecimal (value);
  776. if (typeof(SqlDateTime) == conversionType) return ConvertToSqlDateTime (value);
  777. if (typeof(SqlBoolean) == conversionType) return ConvertToSqlBoolean (value);
  778. if (typeof(SqlMoney) == conversionType) return ConvertToSqlMoney (value);
  779. if (typeof(SqlGuid) == conversionType) return ConvertToSqlGuid (value);
  780. if (typeof(SqlDouble) == conversionType) return ConvertToSqlDouble (value);
  781. if (typeof(SqlByte) == conversionType) return ConvertToSqlByte (value);
  782. if (typeof(SqlInt16) == conversionType) return ConvertToSqlInt16 (value);
  783. if (typeof(SqlInt64) == conversionType) return ConvertToSqlInt64 (value);
  784. if (typeof(SqlSingle) == conversionType) return ConvertToSqlSingle (value);
  785. if (typeof(SqlBinary) == conversionType) return ConvertToSqlBinary (value);
  786. if (typeof(SqlBytes) == conversionType) return ConvertToSqlBytes (value);
  787. if (typeof(SqlChars) == conversionType) return ConvertToSqlChars (value);
  788. if (typeof(SqlXml) == conversionType) return ConvertToSqlXml (value);
  789. #endif
  790. return System.Convert.ChangeType(value, conversionType, Thread.CurrentThread.CurrentCulture);
  791. }
  792. #endregion
  793. #endregion
  794. #region Factory Members
  795. public virtual DataReaderMapper CreateDataReaderMapper(IDataReader dataReader)
  796. {
  797. return new DataReaderMapper(this, dataReader);
  798. }
  799. public virtual DataReaderListMapper CreateDataReaderListMapper(IDataReader reader)
  800. {
  801. return new DataReaderListMapper(CreateDataReaderMapper(reader));
  802. }
  803. public virtual DataReaderMapper CreateDataReaderMapper(
  804. IDataReader dataReader,
  805. NameOrIndexParameter nameOrIndex)
  806. {
  807. return new ScalarDataReaderMapper(this, dataReader, nameOrIndex);
  808. }
  809. public virtual DataReaderListMapper CreateDataReaderListMapper(
  810. IDataReader reader,
  811. NameOrIndexParameter nameOrIndex)
  812. {
  813. return new DataReaderListMapper(CreateDataReaderMapper(reader, nameOrIndex));
  814. }
  815. #if !SILVERLIGHT
  816. public virtual DataRowMapper CreateDataRowMapper(
  817. DataRow row,
  818. DataRowVersion version)
  819. {
  820. return new DataRowMapper(row, version);
  821. }
  822. public virtual DataTableMapper CreateDataTableMapper(
  823. DataTable dataTable,
  824. DataRowVersion version)
  825. {
  826. return new DataTableMapper(dataTable, CreateDataRowMapper(null, version));
  827. }
  828. #endif
  829. public virtual DictionaryMapper CreateDictionaryMapper(IDictionary dictionary)
  830. {
  831. return new DictionaryMapper(dictionary);
  832. }
  833. public virtual DictionaryListMapper CreateDictionaryListMapper(
  834. IDictionary dic,
  835. NameOrIndexParameter keyFieldNameOrIndex,
  836. ObjectMapper objectMapper)
  837. {
  838. return new DictionaryListMapper(dic, keyFieldNameOrIndex, objectMapper);
  839. }
  840. public virtual DictionaryIndexListMapper CreateDictionaryListMapper(
  841. IDictionary dic,
  842. MapIndex index,
  843. ObjectMapper objectMapper)
  844. {
  845. return new DictionaryIndexListMapper(dic, index, objectMapper);
  846. }
  847. public virtual DictionaryListMapper<TK,T> CreateDictionaryListMapper<TK,T>(
  848. IDictionary<TK,T> dic,
  849. NameOrIndexParameter keyFieldNameOrIndex,
  850. ObjectMapper objectMapper)
  851. {
  852. return new DictionaryListMapper<TK,T>(dic, keyFieldNameOrIndex, objectMapper);
  853. }
  854. public virtual DictionaryIndexListMapper<T> CreateDictionaryListMapper<T>(
  855. IDictionary<CompoundValue,T> dic,
  856. MapIndex index,
  857. ObjectMapper objectMapper)
  858. {
  859. return new DictionaryIndexListMapper<T>(dic, index, objectMapper);
  860. }
  861. public virtual EnumeratorMapper CreateEnumeratorMapper(IEnumerator enumerator)
  862. {
  863. return new EnumeratorMapper(enumerator);
  864. }
  865. public virtual ObjectListMapper CreateObjectListMapper(IList list, ObjectMapper objectMapper)
  866. {
  867. return new ObjectListMapper(list, objectMapper);
  868. }
  869. public virtual ScalarListMapper CreateScalarListMapper(IList list, Type type)
  870. {
  871. return new ScalarListMapper(list, type);
  872. }
  873. public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper(IList list, Type type)
  874. {
  875. return new SimpleDestinationListMapper(CreateScalarListMapper(list, type));
  876. }
  877. public virtual SimpleSourceListMapper CreateScalarSourceListMapper(IList list, Type type)
  878. {
  879. return new SimpleSourceListMapper(CreateScalarListMapper(list, type));
  880. }
  881. public virtual ScalarListMapper<T> CreateScalarListMapper<T>(IList<T> list)
  882. {
  883. return new ScalarListMapper<T>(this, list);
  884. }
  885. public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper<T>(IList<T> list)
  886. {
  887. return new SimpleDestinationListMapper(CreateScalarListMapper<T>(list));
  888. }
  889. #endregion
  890. #region GetNullValue
  891. public virtual object GetNullValue(Type type)
  892. {
  893. return TypeAccessor.GetNullValue(type);
  894. }
  895. public virtual bool IsNull(object value)
  896. {
  897. return TypeAccessor.IsNull(value);
  898. }
  899. #endregion
  900. #region GetMapValues
  901. private readonly Dictionary<Type,MapValue[]> _mapValues = new Dictionary<Type,MapValue[]>();
  902. public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] Type type)
  903. {
  904. if (type == null) throw new ArgumentNullException("type");
  905. lock (_mapValues)
  906. {
  907. MapValue[] mapValues;
  908. if (_mapValues.TryGetValue(type, out mapValues))
  909. return mapValues;
  910. var typeExt = TypeExtension.GetTypeExtension(type, Extensions);
  911. bool isSet;
  912. mapValues = MetadataProvider.GetMapValues(typeExt, type, out isSet);
  913. _mapValues.Add(type, mapValues);
  914. return mapValues;
  915. }
  916. }
  917. private readonly Dictionary<MemberAccessor, MapValue[]> _memberMapValues = new Dictionary<MemberAccessor, MapValue[]>();
  918. private Type GetMapValueType(MapValue[] mapValues)
  919. {
  920. if (mapValues != null)
  921. {
  922. var value = mapValues.SelectMany(mv => mv.MapValues).FirstOrDefault();
  923. if (value != null)
  924. {
  925. return value.GetType();
  926. }
  927. }
  928. return null;
  929. }
  930. public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] MemberAccessor memberAccessor)
  931. {
  932. if (memberAccessor == null) throw new ArgumentNullException("memberAccessor");
  933. lock (_memberMapValues)
  934. {
  935. MapValue[] mapValues;
  936. if (_memberMapValues.TryGetValue(memberAccessor, out mapValues))
  937. return mapValues;
  938. var typeExt = TypeExtension.GetTypeExtension(memberAccessor.Type, Extensions);
  939. bool isSet;
  940. mapValues = MetadataProvider.GetMapValues(typeExt, memberAccessor, out isSet);
  941. _memberMapValues.Add(memberAccessor, mapValues);
  942. return mapValues;
  943. }
  944. }
  945. #endregion
  946. #region GetDefaultValue
  947. private readonly Dictionary<Type,object> _defaultValues = new Dictionary<Type,object>();
  948. public virtual object GetDefaultValue([JetBrains.Annotations.NotNull] Type type)
  949. {
  950. if (type == null) throw new ArgumentNullException("type");
  951. lock (_defaultValues)
  952. {
  953. object defaultValue;
  954. if (_defaultValues.TryGetValue(type, out defaultValue))
  955. return defaultValue;
  956. var typeExt = TypeExtension.GetTypeExtension(type, Extensions);
  957. bool isSet;
  958. defaultValue = MetadataProvider.GetDefaultValue(this, typeExt, type, out isSet);
  959. _defaultValues.Add(type, defaultValue = TypeExtension.ChangeType(defaultValue, type));
  960. return defaultValue;
  961. }
  962. }
  963. #endregion
  964. #region GetDataSource, GetDataDestination
  965. [CLSCompliant(false)]
  966. public virtual IMapDataSource GetDataSource(object obj)
  967. {
  968. if (obj == null) throw new ArgumentNullException("obj");
  969. if (obj is IMapDataSource)
  970. return (IMapDataSource)obj;
  971. if (obj is IDataReader)
  972. return CreateDataReaderMapper((IDataReader)obj);
  973. #if !SILVERLIGHT
  974. if (obj is DataRow)
  975. return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default);
  976. if (obj is DataRowView)
  977. return CreateDataRowMapper(
  978. ((DataRowView)obj).Row,
  979. ((DataRowView)obj).RowVersion);
  980. if (obj is DataTable)
  981. return CreateDataRowMapper(((DataTable)(obj)).Rows[0], DataRowVersion.Default);
  982. #endif
  983. if (obj is IDictionary)
  984. return CreateDictionaryMapper((IDictionary)obj);
  985. return GetObjectMapper(obj.GetType());
  986. }
  987. [CLSCompliant(false)]
  988. public virtual IMapDataDestination GetDataDestination(object obj)
  989. {
  990. if (obj == null) throw new ArgumentNullException("obj");
  991. if (obj is IMapDataDestination)
  992. return (IMapDataDestination)obj;
  993. #if !SILVERLIGHT
  994. if (obj is DataRow)
  995. return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default);
  996. if (obj is DataRowView)
  997. return CreateDataRowMapper(
  998. ((DataRowView)obj).Row,
  999. ((DataRowView)obj).RowVersion);
  1000. if (obj is DataTable)
  1001. {
  1002. DataTable dt = obj as DataTable;
  1003. DataRow dr = dt.NewRow();
  1004. dt.Rows.Add(dr);
  1005. return CreateDataRowMapper(dr, DataRowVersion.Default);
  1006. }
  1007. #endif
  1008. if (obj is IDictionary)
  1009. return CreateDictionaryMapper((IDictionary)obj);
  1010. return GetObjectMapper(obj.GetType());
  1011. }
  1012. [CLSCompliant(false)]
  1013. public virtual IMapDataSourceList GetDataSourceList(object obj)
  1014. {
  1015. if (obj == null) throw new ArgumentNullException("obj");
  1016. if (obj is IMapDataSourceList)
  1017. return (IMapDataSourceList)obj;
  1018. if (obj is IDataReader)
  1019. return CreateDataReaderListMapper((IDataReader)obj);
  1020. Type type = obj.GetType().GetElementType();
  1021. return TypeHelper.IsScalar(type)?
  1022. (IMapDataSourceList)CreateScalarSourceListMapper((IList)obj, type):
  1023. CreateObjectListMapper((IList)obj, CreateObjectMapper(type));
  1024. }
  1025. [CLSCompliant(false)]
  1026. public virtual IMapDataDestinationList GetDataDestinationList(object obj)
  1027. {
  1028. if (obj == null) throw new ArgumentNullException("obj");
  1029. if (obj is IMapDataDestinationList)
  1030. return (IMapDataDestinationList)obj;
  1031. Type type = obj.GetType().GetElementType();
  1032. return TypeHelper.IsScalar(type)?
  1033. (IMapDataDestinationList)CreateScalarDestinationListMapper((IList)obj, type):
  1034. CreateObjectListMapper((IList)obj, CreateObjectMapper(type));
  1035. }
  1036. #endregion
  1037. #region ValueMapper
  1038. [CLSCompliant(false)]
  1039. public virtual IValueMapper DefaultValueMapper
  1040. {
  1041. get { return ValueMapping.DefaultMapper; }
  1042. }
  1043. internal readonly Dictionary<Type,IValueMapper> SameTypeMappers = new Dictionary<Type,IValueMapper>();
  1044. internal readonly Dictionary<KeyValue,IValueMapper> DifferentTypeMappers = new Dictionary<KeyValue,IValueMapper>();
  1045. [CLSCompliant(false)]
  1046. public void SetValueMapper(
  1047. Type sourceType,
  1048. Type destType,
  1049. IValueMapper mapper)
  1050. {
  1051. if (sourceType == null) sourceType = typeof(object);
  1052. if (destType == null) destType = typeof(object);
  1053. if (sourceType == destType)
  1054. {
  1055. lock (SameTypeMappers)
  1056. {
  1057. if (mapper == null)
  1058. SameTypeMappers.Remove(sourceType);
  1059. else if (SameTypeMappers.ContainsKey(sourceType))
  1060. SameTypeMappers[sourceType] = mapper;
  1061. else
  1062. SameTypeMappers.Add(sourceType, mapper);
  1063. }
  1064. }
  1065. else
  1066. {
  1067. KeyValue key = new KeyValue(sourceType, destType);
  1068. lock (DifferentTypeMappers)
  1069. {
  1070. if (mapper == null)
  1071. DifferentTypeMappers.Remove(key);
  1072. else if (DifferentTypeMappers.ContainsKey(key))
  1073. DifferentTypeMappers[key] = mapper;
  1074. else
  1075. DifferentTypeMappers.Add(key, mapper);
  1076. }
  1077. }
  1078. }
  1079. [CLSCompliant(false)]
  1080. protected internal virtual IValueMapper GetValueMapper(
  1081. Type sourceType,
  1082. Type destType)
  1083. {
  1084. return ValueMapping.GetMapper(sourceType, destType);
  1085. }
  1086. [CLSCompliant(false)]
  1087. internal protected IValueMapper[] GetValueMappers(
  1088. IMapDataSource source,
  1089. IMapDataDestination dest,
  1090. int[] index)
  1091. {
  1092. IValueMapper[] mappers = new IValueMapper[index.Length];
  1093. for (int i = 0; i < index.Length; i++)
  1094. {
  1095. int n = index[i];
  1096. if (n < 0)
  1097. continue;
  1098. if (!source.SupportsTypedValues(i) || !dest.SupportsTypedValues(n))
  1099. {
  1100. mappers[i] = DefaultValueMapper;
  1101. continue;
  1102. }
  1103. Type sourceType = source.GetFieldType(i);
  1104. Type destType = dest. GetFieldType(n);
  1105. if (sourceType == null) sourceType = typeof(object);
  1106. if (destType == null) destType = typeof(object);
  1107. IValueMapper t;
  1108. if (sourceType == destType)
  1109. {
  1110. lock (SameTypeMappers)
  1111. if (!SameTypeMappers.TryGetValue(sourceType, out t))
  1112. SameTypeMappers.Add(sourceType, t = GetValueMapper(sourceType, destType));
  1113. }
  1114. else
  1115. {
  1116. var key = new KeyValue(sourceType, destType);
  1117. lock (DifferentTypeMappers)
  1118. if (!DifferentTypeMappers.TryGetValue(key, out t))
  1119. DifferentTypeMappers[key] = t = GetValueMapper(sourceType, destType);
  1120. }
  1121. mappers[i] = t;
  1122. }
  1123. return mappers;
  1124. }
  1125. #endregion
  1126. #region Base Mapping
  1127. [CLSCompliant(false)]
  1128. internal protected static int[] GetIndex(
  1129. IMapDataSource source,
  1130. IMapDataDestination dest)
  1131. {
  1132. int count = source.Count;
  1133. int[] index = new int[count];
  1134. for (int i = 0; i < count; i++)
  1135. index[i] = dest.GetOrdinal(source.GetName(i));
  1136. return index;
  1137. }
  1138. [CLSCompliant(false), Obsolete]
  1139. protected static void MapInternal(
  1140. IMapDataSource source, object sourceObject,
  1141. IMapDataDestination dest, object destObject,
  1142. int[] index)
  1143. {
  1144. for (int i = 0; i < index.Length; i++)
  1145. {
  1146. int n = index[i];
  1147. if (n >= 0)
  1148. dest.SetValue(destObject, n, source.GetValue(sourceObject, i));
  1149. }
  1150. }
  1151. [CLSCompliant(false)]
  1152. internal protected static void MapInternal(
  1153. IMapDataSource source, object sourceObject,
  1154. IMapDataDestination dest, object destObject,
  1155. int[] index,
  1156. IValueMapper[] mappers)
  1157. {
  1158. for (int i = 0; i < index.Length; i++)
  1159. {
  1160. int n = index[i];
  1161. if (n >= 0)
  1162. mappers[i].Map(source, sourceObject, i, dest, destObject, n);
  1163. }
  1164. }
  1165. [CLSCompliant(false)]
  1166. protected virtual void MapInternal(
  1167. InitContext initContext,
  1168. IMapDataSource source, object sourceObject,
  1169. IMapDataDestination dest, object destObject,
  1170. params object[] parameters)
  1171. {
  1172. ISupportMapping smSource = sourceObject as ISupportMapping;
  1173. ISupportMapping smDest = destObject as ISupportMapping;
  1174. if (smSource != null)
  1175. {
  1176. if (initContext == null)
  1177. {
  1178. initContext = new InitContext();
  1179. initContext.MappingSchema = this;
  1180. initContext.DataSource = source;
  1181. initContext.SourceObject = sourceObject;
  1182. initContext.ObjectMapper = dest as ObjectMapper;
  1183. initContext.Parameters = parameters;
  1184. }
  1185. initContext.IsSource = true;
  1186. smSource.BeginMapping(initContext);
  1187. initContext.IsSource = false;
  1188. if (initContext.StopMapping)
  1189. return;
  1190. }
  1191. if (smDest != null)
  1192. {
  1193. if (initContext == null)
  1194. {
  1195. initContext = new InitContext();
  1196. initContext.MappingSchema = this;
  1197. initContext.DataSource = source;
  1198. initContext.SourceObject = sourceObject;
  1199. initContext.ObjectMapper = dest as ObjectMapper;
  1200. initContext.Parameters = parameters;
  1201. }
  1202. smDest.BeginMapping(initContext);
  1203. if (initContext.StopMapping)
  1204. return;
  1205. if (dest != initContext.ObjectMapper && initContext.ObjectMapper != null)
  1206. dest = initContext.ObjectMapper;
  1207. }
  1208. int[] index = GetIndex (source, dest);
  1209. IValueMapper[] mappers = GetValueMappers(source, dest, index);
  1210. MapInternal(source, sourceObject, dest, destObject, index, mappers);
  1211. if (smDest != null)
  1212. smDest.EndMapping(initContext);
  1213. if (smSource != null)
  1214. {
  1215. initContext.IsSource = true;
  1216. smSource.EndMapping(initContext);
  1217. initContext.IsSource = false;
  1218. }
  1219. }
  1220. protected virtual object MapInternal(InitContext initContext)
  1221. {
  1222. object dest = initContext.ObjectMapper.CreateInstance(initContext);
  1223. if (initContext.StopMapping == false)
  1224. {
  1225. MapInternal(initContext,
  1226. initContext.DataSource, initContext.SourceObject,
  1227. initContext.ObjectMapper, dest,
  1228. initContext.Parameters);
  1229. }
  1230. return dest;
  1231. }
  1232. [CLSCompliant(false)]
  1233. public void MapSourceToDestination(
  1234. IMapDataSource source, object sourceObject,
  1235. IMapDataDestination dest, object destObject,
  1236. params object[] parameters)
  1237. {
  1238. MapInternal(null, source, sourceObject, dest, destObject, parameters);
  1239. }
  1240. public void MapSourceToDestination(
  1241. object sourceObject,
  1242. object destObject,
  1243. params object[] parameters)
  1244. {
  1245. IMapDataSource source = GetDataSource (sourceObject);
  1246. IMapDataDestination dest = GetDataDestination(destObject);
  1247. MapInternal(null, source, sourceObject, dest, destObject, parameters);
  1248. }
  1249. private static readonly ObjectMapper _nullMapper = new ObjectMapper();
  1250. private class MapInfo
  1251. {
  1252. public int[] Index;
  1253. public IValueMapper[] Mappers;
  1254. }
  1255. [CLSCompliant(false)]
  1256. public virtual void MapSourceListToDestinationList(
  1257. IMapDataSourceList dataSourceList,
  1258. IMapDataDestinationList dataDestinationList,
  1259. params object[] parameters)
  1260. {
  1261. if (dataSourceList == null) throw new ArgumentNullException("dataSourceList");
  1262. if (dataDestinationList == null) throw new ArgumentNullException("dataDestinationList");
  1263. Dictionary<ObjectMapper,MapInfo> infos = new Dictionary<ObjectMapper,MapInfo>();
  1264. InitContext ctx = new InitContext();
  1265. ctx.MappingSchema = this;
  1266. ctx.Parameters = parameters;
  1267. dataSourceList. InitMapping(ctx); if (ctx.StopMapping) return;
  1268. dataDestinationList.InitMapping(ctx); if (ctx.StopMapping) return;
  1269. int[] index = null;
  1270. IValueMapper[] mappers = null;
  1271. ObjectMapper current = _nullMapper;
  1272. IMapDataDestination dest = dataDestinationList.GetDataDestination(ctx);
  1273. ObjectMapper om = dest as ObjectMapper;
  1274. while (dataSourceList.SetNextDataSource(ctx))
  1275. {
  1276. ctx.ObjectMapper = om;
  1277. ctx.StopMapping = false;
  1278. object destObject = dataDestinationList.GetNextObject(ctx);
  1279. if (ctx.StopMapping) continue;
  1280. ISupportMapping smSource = ctx.SourceObject as ISupportMapping;
  1281. ISupportMapping smDest = destObject as ISupportMapping;
  1282. if (smSource != null)
  1283. {
  1284. ctx.IsSource = true;
  1285. smSource.BeginMapping(ctx);
  1286. ctx.IsSource = false;
  1287. if (ctx.StopMapping)
  1288. continue;
  1289. }
  1290. if (smDest != null)
  1291. {
  1292. smDest.BeginMapping(ctx);
  1293. if (ctx.StopMapping)
  1294. continue;
  1295. }
  1296. IMapDataDestination currentDest = current ?? dest;
  1297. if (current != ctx.ObjectMapper)
  1298. {
  1299. current = ctx.ObjectMapper;
  1300. currentDest = current ?? dest;
  1301. if (current != null)
  1302. {
  1303. MapInfo info;
  1304. if (!infos.TryGetValue(current, out info))
  1305. {
  1306. info = new MapInfo();
  1307. info.Index = GetIndex(ctx.DataSource, currentDest);
  1308. info.Mappers = GetValueMappers(ctx.DataSource, currentDest, info.Index);
  1309. infos.Add(current, info);
  1310. }
  1311. index = info.Index;
  1312. mappers = info.Mappers;
  1313. }
  1314. else
  1315. {
  1316. index = GetIndex(ctx.DataSource, currentDest);
  1317. mappers = GetValueMappers(ctx.DataSource, currentDest, index);
  1318. }
  1319. }
  1320. MapInternal(
  1321. ctx.DataSource,
  1322. ctx.SourceObject,
  1323. currentDest,
  1324. destObject,
  1325. index,
  1326. mappers);
  1327. if (smDest != null)
  1328. smDest.EndMapping(ctx);
  1329. if (smSource != null)
  1330. {
  1331. ctx.IsSource = true;
  1332. smSource.EndMapping(ctx);
  1333. ctx.IsSource = false;
  1334. }
  1335. }
  1336. dataDestinationList.EndMapping(ctx);
  1337. dataSourceList. EndMapping(ctx);
  1338. }
  1339. #endregion
  1340. #region ValueToEnum, EnumToValue
  1341. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
  1342. public virtual object MapValueToEnum(object value, Type type)
  1343. {
  1344. if (value == null)
  1345. return GetNullValue(type);
  1346. MapValue[] mapValues = GetMapValues(type);
  1347. var mapValueType = GetMapValueType(mapValues);
  1348. if (mapValueType != null && value.GetType() != mapValueType)
  1349. {
  1350. value = ConvertChangeType(value, mapValueType);
  1351. }
  1352. if (mapValues != null)
  1353. {
  1354. var comp = (IComparable)value;
  1355. foreach (MapValue mv in mapValues)
  1356. foreach (object mapValue in mv.MapValues)
  1357. {
  1358. try
  1359. {
  1360. if (comp.CompareTo(mapValue) == 0)
  1361. return mv.OrigValue;
  1362. }
  1363. catch (ArgumentException ex)
  1364. {
  1365. Debug.WriteLine(ex.Message, MethodBase.GetCurrentMethod().Name);
  1366. }
  1367. }
  1368. }
  1369. InvalidCastException exInvalidCast = null;
  1370. var enumType = TypeHelper.UnwrapNullableType(type);
  1371. try
  1372. {
  1373. value = ConvertChangeType(value, Enum.GetUnderlyingType(enumType));
  1374. if (Enum.IsDefined(enumType, value))
  1375. {
  1376. // Regular (known) enum field w/o explicit mapping defined.
  1377. //
  1378. return Enum.ToObject(enumType, value);
  1379. }
  1380. }
  1381. catch (InvalidCastException ex)
  1382. {
  1383. exInvalidCast = ex;
  1384. }
  1385. // Default value.
  1386. //
  1387. object defaultValue = GetDefaultValue(type);
  1388. if (defaultValue != null)
  1389. return defaultValue;
  1390. if (exInvalidCast != null)
  1391. {
  1392. // Rethrow an InvalidCastException when no default value specified.
  1393. //
  1394. throw exInvalidCast;
  1395. }
  1396. // At this point we have an undefined enum value.
  1397. //
  1398. return Enum.ToObject(enumType, value);
  1399. }
  1400. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
  1401. public virtual object MapValueToEnum(object value, MemberAccessor ma)
  1402. {
  1403. if (value == null || value is DBNull)
  1404. return GetNullValue(ma.Type);
  1405. MapValue[] mapValues = GetMapValues(ma);
  1406. var mapValueType = GetMapValueType(mapValues);
  1407. if (mapValueType != null && value.GetType() != mapValueType)
  1408. {
  1409. value = ConvertChangeType(value, mapValueType);
  1410. }
  1411. if (mapValues != null)
  1412. {
  1413. var comp = (IComparable)value;
  1414. foreach (MapValue mv in mapValues)
  1415. foreach (object mapValue in mv.MapValues)
  1416. {
  1417. try
  1418. {
  1419. if (comp.CompareTo(mapValue) == 0)
  1420. return mv.OrigValue;
  1421. }
  1422. catch (ArgumentException ex)
  1423. {
  1424. Debug.WriteLine(ex.Message, MethodBase.GetCurrentMethod().Name);
  1425. }
  1426. }
  1427. }
  1428. InvalidCastException exInvalidCast = null;
  1429. var enumType = TypeHelper.UnwrapNullableType(ma.Type);
  1430. try
  1431. {
  1432. value = ConvertChangeType(value, Enum.GetUnderlyingType(enumType));
  1433. if (Enum.IsDefined(enumType, value))
  1434. {
  1435. // Re…

Large files files are truncated, but you can click here to view the full file