PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/Mapping/MappingSchema.cs

https://github.com/MaceWindu/bltoolkit
C# | 3891 lines | 3042 code | 814 blank | 35 comment | 503 complexity | efa4f7472e8e0586a116fbdb3860857a MD5 | raw file
Possible License(s): Apache-2.0

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. {
  711. return MapValueToEnum(value, conversionType);
  712. }
  713. if (isNullable)
  714. {
  715. if (TypeHelper.IsNullable(conversionType))
  716. {
  717. // Return a null reference or boxed not null value.
  718. //
  719. return value == null || value is DBNull? null:
  720. ConvertChangeType(value, conversionType.GetGenericArguments()[0]);
  721. }
  722. Type type = conversionType.IsEnum? Enum.GetUnderlyingType(conversionType): conversionType;
  723. switch (Type.GetTypeCode(type))
  724. {
  725. case TypeCode.Boolean: return ConvertToNullableBoolean (value);
  726. case TypeCode.Byte: return ConvertToNullableByte (value);
  727. case TypeCode.Char: return ConvertToNullableChar (value);
  728. case TypeCode.DateTime: return ConvertToNullableDateTime(value);
  729. case TypeCode.Decimal: return ConvertToNullableDecimal (value);
  730. case TypeCode.Double: return ConvertToNullableDouble (value);
  731. case TypeCode.Int16: return ConvertToNullableInt16 (value);
  732. case TypeCode.Int32: return ConvertToNullableInt32 (value);
  733. case TypeCode.Int64: return ConvertToNullableInt64 (value);
  734. case TypeCode.SByte: return ConvertToNullableSByte (value);
  735. case TypeCode.Single: return ConvertToNullableSingle (value);
  736. case TypeCode.UInt16: return ConvertToNullableUInt16 (value);
  737. case TypeCode.UInt32: return ConvertToNullableUInt32 (value);
  738. case TypeCode.UInt64: return ConvertToNullableUInt64 (value);
  739. }
  740. if (typeof(Guid) == conversionType) return ConvertToNullableGuid(value);
  741. if (typeof(DateTimeOffset) == conversionType) return ConvertToNullableDateTimeOffset(value);
  742. if (typeof(TimeSpan) == conversionType) return ConvertToNullableTimeSpan(value);
  743. }
  744. switch (Type.GetTypeCode(conversionType))
  745. {
  746. case TypeCode.Boolean: return ConvertToBoolean (value);
  747. case TypeCode.Byte: return ConvertToByte (value);
  748. case TypeCode.Char: return ConvertToChar (value);
  749. case TypeCode.DateTime: return ConvertToDateTime(value);
  750. case TypeCode.Decimal: return ConvertToDecimal (value);
  751. case TypeCode.Double: return ConvertToDouble (value);
  752. case TypeCode.Int16: return ConvertToInt16 (value);
  753. case TypeCode.Int32: return ConvertToInt32 (value);
  754. case TypeCode.Int64: return ConvertToInt64 (value);
  755. case TypeCode.SByte: return ConvertToSByte (value);
  756. case TypeCode.Single: return ConvertToSingle (value);
  757. case TypeCode.String: return ConvertToString (value);
  758. case TypeCode.UInt16: return ConvertToUInt16 (value);
  759. case TypeCode.UInt32: return ConvertToUInt32 (value);
  760. case TypeCode.UInt64: return ConvertToUInt64 (value);
  761. }
  762. if (typeof(Guid) == conversionType) return ConvertToGuid (value);
  763. if (typeof(Stream) == conversionType) return ConvertToStream (value);
  764. #if !SILVERLIGHT
  765. if (typeof(XmlReader) == conversionType) return ConvertToXmlReader (value);
  766. if (typeof(XmlDocument) == conversionType) return ConvertToXmlDocument (value);
  767. if (typeof(XElement) == conversionType) return ConvertToXElement (value);
  768. #endif
  769. if (typeof(byte[]) == conversionType) return ConvertToByteArray (value);
  770. if (typeof(Binary) == conversionType) return ConvertToLinqBinary (value);
  771. if (typeof(DateTimeOffset) == conversionType) return ConvertToDateTimeOffset(value);
  772. if (typeof(char[]) == conversionType) return ConvertToCharArray (value);
  773. if (typeof(TimeSpan) == conversionType) return ConvertToTimeSpan (value);
  774. #if !SILVERLIGHT
  775. if (typeof(SqlInt32) == conversionType) return ConvertToSqlInt32 (value);
  776. if (typeof(SqlString) == conversionType) return ConvertToSqlString (value);
  777. if (typeof(SqlDecimal) == conversionType) return ConvertToSqlDecimal (value);
  778. if (typeof(SqlDateTime) == conversionType) return ConvertToSqlDateTime (value);
  779. if (typeof(SqlBoolean) == conversionType) return ConvertToSqlBoolean (value);
  780. if (typeof(SqlMoney) == conversionType) return ConvertToSqlMoney (value);
  781. if (typeof(SqlGuid) == conversionType) return ConvertToSqlGuid (value);
  782. if (typeof(SqlDouble) == conversionType) return ConvertToSqlDouble (value);
  783. if (typeof(SqlByte) == conversionType) return ConvertToSqlByte (value);
  784. if (typeof(SqlInt16) == conversionType) return ConvertToSqlInt16 (value);
  785. if (typeof(SqlInt64) == conversionType) return ConvertToSqlInt64 (value);
  786. if (typeof(SqlSingle) == conversionType) return ConvertToSqlSingle (value);
  787. if (typeof(SqlBinary) == conversionType) return ConvertToSqlBinary (value);
  788. if (typeof(SqlBytes) == conversionType) return ConvertToSqlBytes (value);
  789. if (typeof(SqlChars) == conversionType) return ConvertToSqlChars (value);
  790. if (typeof(SqlXml) == conversionType) return ConvertToSqlXml (value);
  791. #endif
  792. return System.Convert.ChangeType(value, conversionType, Thread.CurrentThread.CurrentCulture);
  793. }
  794. #endregion
  795. #endregion
  796. #region Factory Members
  797. public virtual DataReaderMapper CreateDataReaderMapper(IDataReader dataReader)
  798. {
  799. return new DataReaderMapper(this, dataReader);
  800. }
  801. public virtual DataReaderListMapper CreateDataReaderListMapper(IDataReader reader)
  802. {
  803. return new DataReaderListMapper(CreateDataReaderMapper(reader));
  804. }
  805. public virtual DataReaderMapper CreateDataReaderMapper(
  806. IDataReader dataReader,
  807. NameOrIndexParameter nameOrIndex)
  808. {
  809. return new ScalarDataReaderMapper(this, dataReader, nameOrIndex);
  810. }
  811. public virtual DataReaderListMapper CreateDataReaderListMapper(
  812. IDataReader reader,
  813. NameOrIndexParameter nameOrIndex)
  814. {
  815. return new DataReaderListMapper(CreateDataReaderMapper(reader, nameOrIndex));
  816. }
  817. #if !SILVERLIGHT
  818. public virtual DataRowMapper CreateDataRowMapper(
  819. DataRow row,
  820. DataRowVersion version)
  821. {
  822. return new DataRowMapper(row, version);
  823. }
  824. public virtual DataTableMapper CreateDataTableMapper(
  825. DataTable dataTable,
  826. DataRowVersion version)
  827. {
  828. return new DataTableMapper(dataTable, CreateDataRowMapper(null, version));
  829. }
  830. #endif
  831. public virtual DictionaryMapper CreateDictionaryMapper(IDictionary dictionary)
  832. {
  833. return new DictionaryMapper(dictionary);
  834. }
  835. public virtual DictionaryListMapper CreateDictionaryListMapper(
  836. IDictionary dic,
  837. NameOrIndexParameter keyFieldNameOrIndex,
  838. ObjectMapper objectMapper)
  839. {
  840. return new DictionaryListMapper(dic, keyFieldNameOrIndex, objectMapper);
  841. }
  842. public virtual DictionaryIndexListMapper CreateDictionaryListMapper(
  843. IDictionary dic,
  844. MapIndex index,
  845. ObjectMapper objectMapper)
  846. {
  847. return new DictionaryIndexListMapper(dic, index, objectMapper);
  848. }
  849. public virtual DictionaryListMapper<TK,T> CreateDictionaryListMapper<TK,T>(
  850. IDictionary<TK,T> dic,
  851. NameOrIndexParameter keyFieldNameOrIndex,
  852. ObjectMapper objectMapper)
  853. {
  854. return new DictionaryListMapper<TK,T>(dic, keyFieldNameOrIndex, objectMapper);
  855. }
  856. public virtual DictionaryIndexListMapper<T> CreateDictionaryListMapper<T>(
  857. IDictionary<CompoundValue,T> dic,
  858. MapIndex index,
  859. ObjectMapper objectMapper)
  860. {
  861. return new DictionaryIndexListMapper<T>(dic, index, objectMapper);
  862. }
  863. public virtual EnumeratorMapper CreateEnumeratorMapper(IEnumerator enumerator)
  864. {
  865. return new EnumeratorMapper(enumerator);
  866. }
  867. public virtual ObjectListMapper CreateObjectListMapper(IList list, ObjectMapper objectMapper)
  868. {
  869. return new ObjectListMapper(list, objectMapper);
  870. }
  871. public virtual ScalarListMapper CreateScalarListMapper(IList list, Type type)
  872. {
  873. return new ScalarListMapper(list, type);
  874. }
  875. public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper(IList list, Type type)
  876. {
  877. return new SimpleDestinationListMapper(CreateScalarListMapper(list, type));
  878. }
  879. public virtual SimpleSourceListMapper CreateScalarSourceListMapper(IList list, Type type)
  880. {
  881. return new SimpleSourceListMapper(CreateScalarListMapper(list, type));
  882. }
  883. public virtual ScalarListMapper<T> CreateScalarListMapper<T>(IList<T> list)
  884. {
  885. return new ScalarListMapper<T>(this, list);
  886. }
  887. public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper<T>(IList<T> list)
  888. {
  889. return new SimpleDestinationListMapper(CreateScalarListMapper<T>(list));
  890. }
  891. #endregion
  892. #region GetNullValue
  893. public virtual object GetNullValue(Type type)
  894. {
  895. return TypeAccessor.GetNullValue(type);
  896. }
  897. public virtual bool IsNull(object value)
  898. {
  899. return TypeAccessor.IsNull(value);
  900. }
  901. #endregion
  902. #region GetMapValues
  903. private readonly Dictionary<Type,MapValue[]> _mapValues = new Dictionary<Type,MapValue[]>();
  904. public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] Type type)
  905. {
  906. if (type == null) throw new ArgumentNullException("type");
  907. lock (_mapValues)
  908. {
  909. MapValue[] mapValues;
  910. if (_mapValues.TryGetValue(type, out mapValues))
  911. return mapValues;
  912. var typeExt = TypeExtension.GetTypeExtension(type, Extensions);
  913. bool isSet;
  914. mapValues = MetadataProvider.GetMapValues(typeExt, type, out isSet);
  915. _mapValues.Add(type, mapValues);
  916. return mapValues;
  917. }
  918. }
  919. private readonly Dictionary<MemberAccessor, MapValue[]> _memberMapValues = new Dictionary<MemberAccessor, MapValue[]>();
  920. private Type GetMapValueType(MapValue[] mapValues)
  921. {
  922. if (mapValues != null)
  923. {
  924. var value = mapValues.SelectMany(mv => mv.MapValues).FirstOrDefault();
  925. if (value != null)
  926. {
  927. return value.GetType();
  928. }
  929. }
  930. return null;
  931. }
  932. public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] MemberAccessor memberAccessor)
  933. {
  934. if (memberAccessor == null) throw new ArgumentNullException("memberAccessor");
  935. lock (_memberMapValues)
  936. {
  937. MapValue[] mapValues;
  938. if (_memberMapValues.TryGetValue(memberAccessor, out mapValues))
  939. return mapValues;
  940. var typeExt = TypeExtension.GetTypeExtension(memberAccessor.Type, Extensions);
  941. bool isSet;
  942. mapValues = MetadataProvider.GetMapValues(typeExt, memberAccessor, out isSet);
  943. _memberMapValues.Add(memberAccessor, mapValues);
  944. return mapValues;
  945. }
  946. }
  947. #endregion
  948. #region GetDefaultValue
  949. private readonly Dictionary<Type,object> _defaultValues = new Dictionary<Type,object>();
  950. public virtual object GetDefaultValue([JetBrains.Annotations.NotNull] Type type)
  951. {
  952. if (type == null) throw new ArgumentNullException("type");
  953. lock (_defaultValues)
  954. {
  955. object defaultValue;
  956. if (_defaultValues.TryGetValue(type, out defaultValue))
  957. return defaultValue;
  958. var typeExt = TypeExtension.GetTypeExtension(type, Extensions);
  959. bool isSet;
  960. defaultValue = MetadataProvider.GetDefaultValue(this, typeExt, type, out isSet);
  961. _defaultValues.Add(type, defaultValue = TypeExtension.ChangeType(defaultValue, type));
  962. return defaultValue;
  963. }
  964. }
  965. #endregion
  966. #region GetDataSource, GetDataDestination
  967. [CLSCompliant(false)]
  968. public virtual IMapDataSource GetDataSource(object obj)
  969. {
  970. if (obj == null) throw new ArgumentNullException("obj");
  971. if (obj is IMapDataSource)
  972. return (IMapDataSource)obj;
  973. if (obj is IDataReader)
  974. return CreateDataReaderMapper((IDataReader)obj);
  975. #if !SILVERLIGHT
  976. if (obj is DataRow)
  977. return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default);
  978. if (obj is DataRowView)
  979. return CreateDataRowMapper(
  980. ((DataRowView)obj).Row,
  981. ((DataRowView)obj).RowVersion);
  982. if (obj is DataTable)
  983. return CreateDataRowMapper(((DataTable)(obj)).Rows[0], DataRowVersion.Default);
  984. #endif
  985. if (obj is IDictionary)
  986. return CreateDictionaryMapper((IDictionary)obj);
  987. return GetObjectMapper(obj.GetType());
  988. }
  989. [CLSCompliant(false)]
  990. public virtual IMapDataDestination GetDataDestination(object obj)
  991. {
  992. if (obj == null) throw new ArgumentNullException("obj");
  993. if (obj is IMapDataDestination)
  994. return (IMapDataDestination)obj;
  995. #if !SILVERLIGHT
  996. if (obj is DataRow)
  997. return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default);
  998. if (obj is DataRowView)
  999. return CreateDataRowMapper(
  1000. ((DataRowView)obj).Row,
  1001. ((DataRowView)obj).RowVersion);
  1002. if (obj is DataTable)
  1003. {
  1004. DataTable dt = obj as DataTable;
  1005. DataRow dr = dt.NewRow();
  1006. dt.Rows.Add(dr);
  1007. return CreateDataRowMapper(dr, DataRowVersion.Default);
  1008. }
  1009. #endif
  1010. if (obj is IDictionary)
  1011. return CreateDictionaryMapper((IDictionary)obj);
  1012. return GetObjectMapper(obj.GetType());
  1013. }
  1014. [CLSCompliant(false)]
  1015. public virtual IMapDataSourceList GetDataSourceList(object obj)
  1016. {
  1017. if (obj == null) throw new ArgumentNullException("obj");
  1018. if (obj is IMapDataSourceList)
  1019. return (IMapDataSourceList)obj;
  1020. if (obj is IDataReader)
  1021. return CreateDataReaderListMapper((IDataReader)obj);
  1022. Type type = obj.GetType().GetElementType();
  1023. return TypeHelper.IsScalar(type)?
  1024. (IMapDataSourceList)CreateScalarSourceListMapper((IList)obj, type):
  1025. CreateObjectListMapper((IList)obj, CreateObjectMapper(type));
  1026. }
  1027. [CLSCompliant(false)]
  1028. public virtual IMapDataDestinationList GetDataDestinationList(object obj)
  1029. {
  1030. if (obj == null) throw new ArgumentNullException("obj");
  1031. if (obj is IMapDataDestinationList)
  1032. return (IMapDataDestinationList)obj;
  1033. Type type = obj.GetType().GetElementType();
  1034. return TypeHelper.IsScalar(type)?
  1035. (IMapDataDestinationList)CreateScalarDestinationListMapper((IList)obj, type):
  1036. CreateObjectListMapper((IList)obj, CreateObjectMapper(type));
  1037. }
  1038. #endregion
  1039. #region ValueMapper
  1040. [CLSCompliant(false)]
  1041. public virtual IValueMapper DefaultValueMapper
  1042. {
  1043. get { return ValueMapping.DefaultMapper; }
  1044. }
  1045. internal readonly Dictionary<Type,IValueMapper> SameTypeMappers = new Dictionary<Type,IValueMapper>();
  1046. internal readonly Dictionary<KeyValue,IValueMapper> DifferentTypeMappers = new Dictionary<KeyValue,IValueMapper>();
  1047. [CLSCompliant(false)]
  1048. public void SetValueMapper(
  1049. Type sourceType,
  1050. Type destType,
  1051. IValueMapper mapper)
  1052. {
  1053. if (sourceType == null) sourceType = typeof(object);
  1054. if (destType == null) destType = typeof(object);
  1055. if (sourceType == destType)
  1056. {
  1057. lock (SameTypeMappers)
  1058. {
  1059. if (mapper == null)
  1060. SameTypeMappers.Remove(sourceType);
  1061. else if (SameTypeMappers.ContainsKey(sourceType))
  1062. SameTypeMappers[sourceType] = mapper;
  1063. else
  1064. SameTypeMappers.Add(sourceType, mapper);
  1065. }
  1066. }
  1067. else
  1068. {
  1069. KeyValue key = new KeyValue(sourceType, destType);
  1070. lock (DifferentTypeMappers)
  1071. {
  1072. if (mapper == null)
  1073. DifferentTypeMappers.Remove(key);
  1074. else if (DifferentTypeMappers.ContainsKey(key))
  1075. DifferentTypeMappers[key] = mapper;
  1076. else
  1077. DifferentTypeMappers.Add(key, mapper);
  1078. }
  1079. }
  1080. }
  1081. [CLSCompliant(false)]
  1082. protected internal virtual IValueMapper GetValueMapper(
  1083. Type sourceType,
  1084. Type destType)
  1085. {
  1086. return ValueMapping.GetMapper(sourceType, destType);
  1087. }
  1088. [CLSCompliant(false)]
  1089. internal protected IValueMapper[] GetValueMappers(
  1090. IMapDataSource source,
  1091. IMapDataDestination dest,
  1092. int[] index)
  1093. {
  1094. IValueMapper[] mappers = new IValueMapper[index.Length];
  1095. for (int i = 0; i < index.Length; i++)
  1096. {
  1097. int n = index[i];
  1098. if (n < 0)
  1099. continue;
  1100. if (!source.SupportsTypedValues(i) || !dest.SupportsTypedValues(n))
  1101. {
  1102. mappers[i] = DefaultValueMapper;
  1103. continue;
  1104. }
  1105. Type sourceType = source.GetFieldType(i);
  1106. Type destType = dest. GetFieldType(n);
  1107. if (sourceType == null) sourceType = typeof(object);
  1108. if (destType == null) destType = typeof(object);
  1109. IValueMapper t;
  1110. if (sourceType == destType)
  1111. {
  1112. lock (SameTypeMappers)
  1113. if (!SameTypeMappers.TryGetValue(sourceType, out t))
  1114. SameTypeMappers.Add(sourceType, t = GetValueMapper(sourceType, destType));
  1115. }
  1116. else
  1117. {
  1118. var key = new KeyValue(sourceType, destType);
  1119. lock (DifferentTypeMappers)
  1120. if (!DifferentTypeMappers.TryGetValue(key, out t))
  1121. DifferentTypeMappers[key] = t = GetValueMapper(sourceType, destType);
  1122. }
  1123. mappers[i] = t;
  1124. }
  1125. return mappers;
  1126. }
  1127. #endregion
  1128. #region Base Mapping
  1129. [CLSCompliant(false)]
  1130. internal protected static int[] GetIndex(
  1131. IMapDataSource source,
  1132. IMapDataDestination dest)
  1133. {
  1134. int count = source.Count;
  1135. int[] index = new int[count];
  1136. for (int i = 0; i < count; i++)
  1137. index[i] = dest.GetOrdinal(source.GetName(i));
  1138. return index;
  1139. }
  1140. [CLSCompliant(false), Obsolete]
  1141. protected static void MapInternal(
  1142. IMapDataSource source, object sourceObject,
  1143. IMapDataDestination dest, object destObject,
  1144. int[] index)
  1145. {
  1146. for (int i = 0; i < index.Length; i++)
  1147. {
  1148. int n = index[i];
  1149. if (n >= 0)
  1150. dest.SetValue(destObject, n, source.GetValue(sourceObject, i));
  1151. }
  1152. }
  1153. [CLSCompliant(false)]
  1154. internal protected static void MapInternal(
  1155. IMapDataSource source, object sourceObject,
  1156. IMapDataDestination dest, object destObject,
  1157. int[] index,
  1158. IValueMapper[] mappers)
  1159. {
  1160. for (int i = 0; i < index.Length; i++)
  1161. {
  1162. int n = index[i];
  1163. if (n >= 0)
  1164. mappers[i].Map(source, sourceObject, i, dest, destObject, n);
  1165. }
  1166. }
  1167. [CLSCompliant(false)]
  1168. protected virtual void MapInternal(
  1169. InitContext initContext,
  1170. IMapDataSource source, object sourceObject,
  1171. IMapDataDestination dest, object destObject,
  1172. params object[] parameters)
  1173. {
  1174. ISupportMapping smSource = sourceObject as ISupportMapping;
  1175. ISupportMapping smDest = destObject as ISupportMapping;
  1176. if (smSource != null)
  1177. {
  1178. if (initContext == null)
  1179. {
  1180. initContext = new InitContext();
  1181. initContext.MappingSchema = this;
  1182. initContext.DataSource = source;
  1183. initContext.SourceObject = sourceObject;
  1184. initContext.ObjectMapper = dest as ObjectMapper;
  1185. initContext.Parameters = parameters;
  1186. }
  1187. initContext.IsSource = true;
  1188. smSource.BeginMapping(initContext);
  1189. initContext.IsSource = false;
  1190. if (initContext.StopMapping)
  1191. return;
  1192. }
  1193. if (smDest != null)
  1194. {
  1195. if (initContext == null)
  1196. {
  1197. initContext = new InitContext();
  1198. initContext.MappingSchema = this;
  1199. initContext.DataSource = source;
  1200. initContext.SourceObject = sourceObject;
  1201. initContext.ObjectMapper = dest as ObjectMapper;
  1202. initContext.Parameters = parameters;
  1203. }
  1204. smDest.BeginMapping(initContext);
  1205. if (initContext.StopMapping)
  1206. return;
  1207. if (dest != initContext.ObjectMapper && initContext.ObjectMapper != null)
  1208. dest = initContext.ObjectMapper;
  1209. }
  1210. int[] index = GetIndex (source, dest);
  1211. IValueMapper[] mappers = GetValueMappers(source, dest, index);
  1212. MapInternal(source, sourceObject, dest, destObject, index, mappers);
  1213. if (smDest != null)
  1214. smDest.EndMapping(initContext);
  1215. if (smSource != null)
  1216. {
  1217. initContext.IsSource = true;
  1218. smSource.EndMapping(initContext);
  1219. initContext.IsSource = false;
  1220. }
  1221. }
  1222. protected virtual object MapInternal(InitContext initContext)
  1223. {
  1224. object dest = initContext.ObjectMapper.CreateInstance(initContext);
  1225. if (initContext.StopMapping == false)
  1226. {
  1227. MapInternal(initContext,
  1228. initContext.DataSource, initContext.SourceObject,
  1229. initContext.ObjectMapper, dest,
  1230. initContext.Parameters);
  1231. }
  1232. return dest;
  1233. }
  1234. [CLSCompliant(false)]
  1235. public void MapSourceToDestination(
  1236. IMapDataSource source, object sourceObject,
  1237. IMapDataDestination dest, object destObject,
  1238. params object[] parameters)
  1239. {
  1240. MapInternal(null, source, sourceObject, dest, destObject, parameters);
  1241. }
  1242. public void MapSourceToDestination(
  1243. object sourceObject,
  1244. object destObject,
  1245. params object[] parameters)
  1246. {
  1247. IMapDataSource source = GetDataSource (sourceObject);
  1248. IMapDataDestination dest = GetDataDestination(destObject);
  1249. MapInternal(null, source, sourceObject, dest, destObject, parameters);
  1250. }
  1251. private static readonly ObjectMapper _nullMapper = new ObjectMapper();
  1252. private class MapInfo
  1253. {
  1254. public int[] Index;
  1255. public IValueMapper[] Mappers;
  1256. }
  1257. [CLSCompliant(false)]
  1258. public virtual void MapSourceListToDestinationList(
  1259. IMapDataSourceList dataSourceList,
  1260. IMapDataDestinationList dataDestinationList,
  1261. params object[] parameters)
  1262. {
  1263. if (dataSourceList == null) throw new ArgumentNullException("dataSourceList");
  1264. if (dataDestinationList == null) throw new ArgumentNullException("dataDestinationList");
  1265. Dictionary<ObjectMapper,MapInfo> infos = new Dictionary<ObjectMapper,MapInfo>();
  1266. InitContext ctx = new InitContext();
  1267. ctx.MappingSchema = this;
  1268. ctx.Parameters = parameters;
  1269. dataSourceList. InitMapping(ctx); if (ctx.StopMapping) return;
  1270. dataDestinationList.InitMapping(ctx); if (ctx.StopMapping) return;
  1271. int[] index = null;
  1272. IValueMapper[] mappers = null;
  1273. ObjectMapper current = _nullMapper;
  1274. IMapDataDestination dest = dataDestinationList.GetDataDestination(ctx);
  1275. ObjectMapper om = dest as ObjectMapper;
  1276. while (dataSourceList.SetNextDataSource(ctx))
  1277. {
  1278. ctx.ObjectMapper = om;
  1279. ctx.StopMapping = false;
  1280. object destObject = dataDestinationList.GetNextObject(ctx);
  1281. if (ctx.StopMapping) continue;
  1282. ISupportMapping smSource = ctx.SourceObject as ISupportMapping;
  1283. ISupportMapping smDest = destObject as ISupportMapping;
  1284. if (smSource != null)
  1285. {
  1286. ctx.IsSource = true;
  1287. smSource.BeginMapping(ctx);
  1288. ctx.IsSource = false;
  1289. if (ctx.StopMapping)
  1290. continue;
  1291. }
  1292. if (smDest != null)
  1293. {
  1294. smDest.BeginMapping(ctx);
  1295. if (ctx.StopMapping)
  1296. continue;
  1297. }
  1298. IMapDataDestination currentDest = current ?? dest;
  1299. if (current != ctx.ObjectMapper)
  1300. {
  1301. current = ctx.ObjectMapper;
  1302. currentDest = current ?? dest;
  1303. if (current != null)
  1304. {
  1305. MapInfo info;
  1306. if (!infos.TryGetValue(current, out info))
  1307. {
  1308. info = new MapInfo();
  1309. info.Index = GetIndex(ctx.DataSource, currentDest);
  1310. info.Mappers = GetValueMappers(ctx.DataSource, currentDest, info.Index);
  1311. infos.Add(current, info);
  1312. }
  1313. index = info.Index;
  1314. mappers = info.Mappers;
  1315. }
  1316. else
  1317. {
  1318. index = GetIndex(ctx.DataSource, currentDest);
  1319. mappers = GetValueMappers(ctx.DataSource, currentDest, index);
  1320. }
  1321. }
  1322. MapInternal(
  1323. ctx.DataSource,
  1324. ctx.SourceObject,
  1325. currentDest,
  1326. destObject,
  1327. index,
  1328. mappers);
  1329. if (smDest != null)
  1330. smDest.EndMapping(ctx);
  1331. if (smSource != null)
  1332. {
  1333. ctx.IsSource = true;
  1334. smSource.EndMapping(ctx);
  1335. ctx.IsSource = false;
  1336. }
  1337. }
  1338. dataDestinationList.EndMapping(ctx);
  1339. dataSourceList. EndMapping(ctx);
  1340. }
  1341. #endregion
  1342. #region ValueToEnum, EnumToValue
  1343. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
  1344. public virtual object MapValueToEnum(object value, Type type)
  1345. {
  1346. if (value == null || value == DBNull.Value)
  1347. return GetNullValue(type);
  1348. MapValue[] mapValues = GetMapValues(type);
  1349. var mapValueType = GetMapValueType(mapValues);
  1350. if (mapValueType != null && value.GetType() != mapValueType)
  1351. {
  1352. value = ConvertChangeType(value, mapValueType);
  1353. }
  1354. if (mapValues != null)
  1355. {
  1356. var comp = (IComparable)value;
  1357. foreach (MapValue mv in mapValues)
  1358. foreach (object mapValue in mv.MapValues)
  1359. {
  1360. try
  1361. {
  1362. if (comp.CompareTo(mapValue) == 0)
  1363. return mv.OrigValue;
  1364. }
  1365. catch (ArgumentException ex)
  1366. {
  1367. Debug.WriteLine(ex.Message, MethodBase.GetCurrentMethod().Name);
  1368. }
  1369. }
  1370. }
  1371. InvalidCastException exInvalidCast = null;
  1372. var enumType = TypeHelper.UnwrapNullableType(type);
  1373. try
  1374. {
  1375. value = ConvertChangeType(value, Enum.GetUnderlyingType(enumType));
  1376. if (Enum.IsDefined(enumType, value))
  1377. {
  1378. // Regular (known) enum field w/o explicit mapping defined.
  1379. //
  1380. return Enum.ToObject(enumT

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