diff Source/Mapping/ObjectMapper.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Mapping/ObjectMapper.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,786 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+
+namespace BLToolkit.Mapping
+{
+	using DataAccess;
+	using Reflection;
+	using Reflection.Extension;
+	using Reflection.MetadataProvider;
+
+	[DebuggerDisplay("Type = {TypeAccessor.Type}, OriginalType = {TypeAccessor.OriginalType}")]
+	public class ObjectMapper : MapDataSourceDestinationBase, IEnumerable<MemberMapper>
+	{
+		#region Protected Members
+
+		protected virtual MemberMapper CreateMemberMapper(MapMemberInfo mapMemberInfo)
+		{
+			if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo");
+
+			MemberMapper mm = null;
+
+			var attr = mapMemberInfo.MemberAccessor.GetAttribute<MemberMapperAttribute>();
+
+			MemberExtension ext;
+
+			if (_extension != null && _extension.Members.TryGetValue(mapMemberInfo.MemberName,out ext))
+			{
+				AttributeExtensionCollection attrExt;
+
+				if (ext.Attributes.TryGetValue("MemberMapper", out attrExt))
+				{
+					attr = new MemberMapperAttribute((Type)attrExt[0].Values["MemberMapperType"]);
+				}
+			}
+
+			if (attr == null)
+			{
+				var attrs = TypeHelper.GetAttributes(mapMemberInfo.Type, typeof(MemberMapperAttribute));
+
+				foreach (MemberMapperAttribute a in attrs)
+				{
+					if (a.MemberType == null)
+					{
+						mm = a.MemberMapper;
+						break;
+					}
+				}
+			}
+			else
+				mm = attr.MemberMapper;
+
+			if (mm == null)
+			{
+				var attrs = TypeHelper.GetAttributes(
+					mapMemberInfo.MemberAccessor.MemberInfo.DeclaringType, typeof(MemberMapperAttribute));
+
+				foreach (MemberMapperAttribute a in attrs)
+				{
+					if (a.MemberType == mapMemberInfo.Type)
+					{
+						mm = a.MemberMapper;
+						break;
+					}
+				}
+			}
+
+			if (mm == null)
+				mm = MemberMapper.CreateMemberMapper(mapMemberInfo);
+
+			mm.Init(mapMemberInfo);
+
+			return mm;
+		}
+
+		[SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "stack1")]
+		protected virtual void Add(MemberMapper memberMapper)
+		{
+			if (memberMapper == null) throw new ArgumentNullException("memberMapper");
+
+			memberMapper.SetOrdinal(_members.Count);
+
+			_members           .Add(memberMapper);
+			_nameToMember      .Add(memberMapper.Name.ToLower(), memberMapper);
+			_memberNameToMember.Add(memberMapper.MemberName,     memberMapper);
+		}
+
+		protected virtual MetadataProviderBase CreateMetadataProvider()
+		{
+			return MetadataProviderBase.CreateProvider();
+		}
+
+		#endregion
+
+		#region Public Members
+
+		private readonly List<MemberMapper> _members = new List<MemberMapper>();
+		public  MemberMapper this[int index]
+		{
+			get { return _members[index]; }
+		}
+
+		readonly List<Association> _associations = new List<Association>();
+		public   List<Association>  Associations
+		{
+			get { return _associations; }
+		}
+
+		readonly List<InheritanceMappingAttribute> _inheritanceMapping = new List<InheritanceMappingAttribute>();
+		public   List<InheritanceMappingAttribute>  InheritanceMapping
+		{
+			get { return _inheritanceMapping; }
+		}
+
+		[CLSCompliant(false)]
+		protected TypeExtension _extension;
+		public  TypeExtension  Extension
+		{
+			get { return _extension;  }
+			set { _extension = value; }
+		}
+
+		private MetadataProviderBase _metadataProvider;
+		public  MetadataProviderBase  MetadataProvider
+		{
+			get { return _metadataProvider ?? (_metadataProvider = CreateMetadataProvider()); }
+			set { _metadataProvider = value; }
+		}
+
+		private string[] _fieldNames;
+		public  string[]  FieldNames
+		{
+			get
+			{
+				if (_fieldNames == null)
+				{
+					_fieldNames = new string[_members.Count];
+
+					for (var i = 0; i < _fieldNames.Length; i++)
+					{
+						_fieldNames[i] = _members[i].Name;
+					}
+				}
+
+				return _fieldNames;
+			}
+		}
+
+		private readonly Dictionary<string,MemberMapper> _nameToMember       = new Dictionary<string,MemberMapper>();
+		private readonly Dictionary<string,MemberMapper> _memberNameToMember = new Dictionary<string,MemberMapper>();
+		public  MemberMapper this[string name]
+		{
+			get
+			{
+				if (name == null) throw new ArgumentNullException("name");
+
+				lock (_nameToMember)
+				{
+					MemberMapper mm;
+
+					if (!_nameToMember.TryGetValue(name, out mm))
+					{
+						if (!_nameToMember.TryGetValue(name.ToLower(CultureInfo.CurrentCulture), out mm))
+						{
+							lock (_memberNameToMember)
+								if (_memberNameToMember.ContainsKey(name) || _memberNameToMember.ContainsKey(name.ToLower(CultureInfo.CurrentCulture)))
+									return null;
+
+							mm = GetComplexMapper(name, name);
+
+							if (mm != null)
+							{
+								if (_members.Contains(mm))
+								{
+									//throw new MappingException(string.Format(
+									//    "Wrong mapping field name: '{0}', type: '{1}'. Use field name '{2}' instead.",
+									//    name, _typeAccessor.OriginalType.Name, mm.Name));
+									return null;
+								}
+
+								Add(mm);
+							}
+						}
+						else
+							_nameToMember.Add(name, mm);
+					}
+
+					return mm;
+				}
+			}
+		}
+
+		public MemberMapper this[string name, bool byPropertyName]
+		{
+			get
+			{
+				MemberMapper mm;
+
+				if (byPropertyName)
+					lock (_memberNameToMember)
+						return _memberNameToMember.TryGetValue(name, out mm) ? mm : null;
+
+				return this[name];
+			}
+		}
+
+		public int GetOrdinal(string name, bool byPropertyName)
+		{
+			if (byPropertyName)
+			{
+				for (var i = 0; i < _members.Count; ++i)
+					if (_members[i].MemberName == name)
+						return i;
+
+				return -1;
+			}
+
+			return GetOrdinal(name);
+		}
+
+		[CLSCompliant(false)]
+		protected TypeAccessor _typeAccessor;
+		public  TypeAccessor  TypeAccessor
+		{
+			get { return _typeAccessor; }
+		}
+
+		private MappingSchema _mappingSchema;
+		public  MappingSchema  MappingSchema
+		{
+			get { return _mappingSchema; }
+		}
+
+		#endregion
+
+		#region Init Mapper
+
+		public virtual void Init(MappingSchema mappingSchema, Type type)
+		{
+			if (type == null) throw new ArgumentNullException("type");
+
+			_typeAccessor  = TypeAccessor.GetAccessor(type);
+			_mappingSchema = mappingSchema;
+			_extension     = TypeExtension.GetTypeExtension(_typeAccessor.OriginalType, mappingSchema.Extensions);
+
+			_inheritanceMapping.AddRange(GetInheritanceMapping());
+
+			foreach (MemberAccessor ma in _typeAccessor)
+			{
+				var a = GetAssociation(ma);
+
+				if (a != null)
+				{
+					_associations.Add(a);
+					continue;
+				}
+
+				if (GetMapIgnore(ma))
+					continue;
+
+			    var mapFieldAttr = GetMapField(ma); // ma.GetAttribute<MapFieldAttribute>();
+
+				if (mapFieldAttr == null || (mapFieldAttr.OrigName == null && mapFieldAttr.Format == null))
+				{
+					var mi = new MapMemberInfo();
+
+				    var dbTypeAttribute = GetDbType(ma); // ma.GetAttribute<DbTypeAttribute>();
+
+					if (dbTypeAttribute != null)
+					{
+						mi.DbType      = dbTypeAttribute.DbType;
+						mi.IsDbTypeSet = true;
+
+						if (dbTypeAttribute.Size != null)
+						{
+							mi.DbSize      = dbTypeAttribute.Size.Value;
+							mi.IsDbSizeSet = true;
+						}
+					}
+
+					mi.MemberAccessor             = ma;
+					mi.Type                       = ma.Type;
+					mi.MappingSchema              = mappingSchema;
+					mi.MemberExtension            = _extension[ma.Name];
+					mi.Name                       = GetFieldName   (ma);
+					mi.MemberName                 = ma.Name;
+					mi.Storage                    = GetFieldStorage(ma);
+					mi.IsInheritanceDiscriminator = GetInheritanceDiscriminator(ma);
+					mi.Trimmable                  = GetTrimmable   (ma);
+					mi.SqlIgnore                  = GetSqlIgnore   (ma);
+					mi.MapValues                  = GetMapValues   (ma);
+					mi.DefaultValue               = GetDefaultValue(ma);
+					mi.Nullable                   = GetNullable    (ma);
+					mi.NullValue                  = GetNullValue   (ma, mi.Nullable);
+
+					Add(CreateMemberMapper(mi));
+				}
+				else if (mapFieldAttr.OrigName != null)
+				{
+					EnsureMapper(mapFieldAttr.MapName, ma.Name + "." + mapFieldAttr.OrigName);
+				}
+				else //if (mapFieldAttr.Format != null)
+				{
+					foreach (MemberMapper inner in _mappingSchema.GetObjectMapper(ma.Type))
+						EnsureMapper(string.Format(mapFieldAttr.Format, inner.Name), ma.Name + "." + inner.MemberName);
+				}
+			}
+
+			foreach (var ae in _extension.Attributes["MapField"])
+			{
+				var mapName  = (string)ae["MapName"];
+				var origName = (string)ae["OrigName"];
+
+				if (mapName == null || origName == null)
+					throw new MappingException(string.Format(
+						"Type '{0}' has invalid  extension. MapField MapName='{1}' OrigName='{2}'.",
+							type.FullName, mapName, origName));
+
+				EnsureMapper(mapName, origName);
+			}
+
+			MetadataProvider.EnsureMapper(TypeAccessor, MappingSchema, EnsureMapper);
+		}
+
+		private MemberMapper EnsureMapper(string mapName, string origName)
+		{
+			var mm = this[mapName];
+
+			if (mm == null)
+			{
+				var name = mapName.ToLower();
+
+				foreach (var m in _members)
+				{
+					if (m.MemberAccessor.Name.ToLower() == name)
+					{
+						_nameToMember.Add(name, m);
+						return m;
+					}
+				}
+
+				mm = GetComplexMapper(mapName, origName);
+
+				if (mm != null)
+					Add(mm);
+			}
+
+			return mm;
+		}
+
+		private readonly Dictionary<string,MemberMapper> _nameToComplexMapper = new Dictionary<string,MemberMapper>();
+
+		[SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "stack0")]
+		[SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "origName")]
+		protected MemberMapper GetComplexMapper(string mapName, string origName)
+		{
+			if (origName == null) throw new ArgumentNullException("origName");
+
+			var name = origName.ToLower();
+			var idx  = origName.IndexOf('.');
+
+			lock (_nameToComplexMapper)
+			{
+				MemberMapper mm;
+
+				if (_nameToComplexMapper.TryGetValue(name, out mm))
+					return mm;
+
+				if (idx > 0)
+				{
+					name = name.Substring(0, idx);
+
+					foreach (MemberAccessor ma in TypeAccessor)
+					{
+						if (ma.Name.Length == name.Length && ma.Name.ToLower() == name)
+						{
+							var om = MappingSchema.GetObjectMapper(ma.Type);
+
+							if (om != null)
+							{
+								mm = om.GetComplexMapper(mapName, origName.Substring(idx + 1));
+
+								if (mm != null)
+								{
+									var mi = new MapMemberInfo
+									{
+										MemberAccessor        = ma,
+										ComplexMemberAccessor = mm.ComplexMemberAccessor,
+										Type                  = mm.Type,
+										MappingSchema         = MappingSchema,
+										Name                  = mapName,
+										MemberName            = origName
+									};
+
+									var mapper = new MemberMapper.ComplexMapper(mm);
+									var key    = origName.ToLower();
+
+									mapper.Init(mi);
+
+									if (_nameToComplexMapper.ContainsKey(key))
+										_nameToComplexMapper[key] = mapper;
+									else
+										_nameToComplexMapper.Add(key, mapper);
+
+									return mapper;
+								}
+							}
+
+							break;
+						}
+					}
+				}
+				else
+				{
+					foreach (var m in _members)
+						if (m.MemberAccessor.Name.Length == name.Length && m.MemberAccessor.Name.ToLower() == name)
+						{
+							if (_nameToComplexMapper.ContainsKey(name))
+								_nameToComplexMapper[name] = m;
+							else
+								_nameToComplexMapper.Add(name, m);
+
+							return m;
+						}
+				}
+
+				// Under some conditions, this way lead to memory leaks.
+				// In other hand, shaking mappers up every time lead to performance loss.
+				// So we cache failed requests.
+				// If this optimization is a memory leak for you, just comment out next line.
+				//
+				if (_nameToComplexMapper.ContainsKey(name))
+					_nameToComplexMapper[name] = null;
+				else
+					_nameToComplexMapper.Add(name, null);
+
+				return null;
+			}
+
+		}
+
+		private MapValue[] GetMapValues(MemberAccessor member)
+		{
+			bool isSet;
+
+			var values = MetadataProvider.GetMapValues(Extension, member, out isSet);
+
+			return isSet? values: _mappingSchema.GetMapValues(member.Type);
+		}
+
+		protected virtual object GetDefaultValue(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+
+			var value = MetadataProvider.GetDefaultValue(MappingSchema, Extension, memberAccessor, out isSet);
+
+			return isSet? value: _mappingSchema.GetDefaultValue(memberAccessor.Type);
+		}
+
+		protected virtual bool GetNullable(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetNullable(MappingSchema, Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual bool GetLazyInstance(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetLazyInstance(MappingSchema, Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual bool GetMapIgnore(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetMapIgnore(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual MapFieldAttribute GetMapField(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetMapField(Extension, memberAccessor, out isSet);
+		}
+
+		[CLSCompliant(false)]
+		protected virtual DbTypeAttribute GetDbType(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetDbType(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual PrimaryKeyAttribute GetPrimaryKey(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetPrimaryKey(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual bool GetSqlIgnore(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetSqlIgnore(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual string GetFieldName(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetFieldName(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual string GetFieldStorage(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetFieldStorage(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual bool GetInheritanceDiscriminator(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetInheritanceDiscriminator(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual bool GetTrimmable(MemberAccessor memberAccessor)
+		{
+			bool isSet;
+			return MetadataProvider.GetTrimmable(Extension, memberAccessor, out isSet);
+		}
+
+		protected virtual object GetNullValue(MemberAccessor memberAccessor, bool isNullable)
+		{
+			if (isNullable)
+			{
+				bool isSet;
+				return MetadataProvider.GetNullValue(MappingSchema, Extension, memberAccessor, out isSet);
+			}
+
+			return MappingSchema.GetNullValue(memberAccessor.Type);
+		}
+
+		protected virtual Association GetAssociation(MemberAccessor memberAccessor)
+		{
+			return MetadataProvider.GetAssociation(Extension, memberAccessor);
+		}
+
+		protected virtual InheritanceMappingAttribute[] GetInheritanceMapping()
+		{
+			return MetadataProvider.GetInheritanceMapping(_typeAccessor.OriginalType, Extension);
+		}
+
+		#endregion
+
+		#region IObjectMappper Members
+
+		public virtual object CreateInstance()
+		{
+			return _typeAccessor.CreateInstanceEx();
+		}
+
+		public virtual object CreateInstance(InitContext context)
+		{
+			return _typeAccessor.CreateInstanceEx(context);
+		}
+
+		#endregion
+
+		#region IMapDataSource Members
+
+		public override int Count
+		{
+			get { return _members.Count; }
+		}
+
+		public override Type GetFieldType(int index)
+		{
+			return _members[index].Type;
+		}
+
+		public override string GetName(int index)
+		{
+			return _members[index].Name;
+		}
+
+		public override object GetValue(object o, int index)
+		{
+			return _members[index].GetValue(o);
+		}
+
+		public override object GetValue(object o, string name)
+		{
+			MemberMapper mm;
+
+			lock (_nameToMember)
+				if (!_nameToMember.TryGetValue(name, out mm))
+					mm = this[name];
+
+			return mm == null? null: mm.GetValue(o);
+		}
+
+		public override bool     IsNull     (object o, int index) { return this[index].IsNull(o);      }
+
+		public override bool     SupportsTypedValues(int index)   { return this[index].SupportsValue;  }
+
+		// Simple type getters.
+		//
+		[CLSCompliant(false)]
+		public override SByte    GetSByte   (object o, int index) { return this[index].GetSByte   (o); }
+		public override Int16    GetInt16   (object o, int index) { return this[index].GetInt16   (o); }
+		public override Int32    GetInt32   (object o, int index) { return this[index].GetInt32   (o); }
+		public override Int64    GetInt64   (object o, int index) { return this[index].GetInt64   (o); }
+
+		public override Byte     GetByte    (object o, int index) { return this[index].GetByte    (o); }
+		[CLSCompliant(false)]
+		public override UInt16   GetUInt16  (object o, int index) { return this[index].GetUInt16  (o); }
+		[CLSCompliant(false)]
+		public override UInt32   GetUInt32  (object o, int index) { return this[index].GetUInt32  (o); }
+		[CLSCompliant(false)]
+		public override UInt64   GetUInt64  (object o, int index) { return this[index].GetUInt64  (o); }
+
+		public override Boolean  GetBoolean (object o, int index) { return this[index].GetBoolean (o); }
+		public override Char     GetChar    (object o, int index) { return this[index].GetChar    (o); }
+		public override Single   GetSingle  (object o, int index) { return this[index].GetSingle  (o); }
+		public override Double   GetDouble  (object o, int index) { return this[index].GetDouble  (o); }
+		public override Decimal  GetDecimal (object o, int index) { return this[index].GetDecimal (o); }
+		public override Guid     GetGuid    (object o, int index) { return this[index].GetGuid    (o); }
+		public override DateTime GetDateTime(object o, int index) { return this[index].GetDateTime(o); }
+		public override DateTimeOffset GetDateTimeOffset(object o, int index) { return this[index].GetDateTimeOffset(o); }
+
+		// Nullable type getters.
+		//
+		[CLSCompliant(false)]
+		public override SByte?    GetNullableSByte   (object o, int index) { return this[index].GetNullableSByte   (o); }
+		public override Int16?    GetNullableInt16   (object o, int index) { return this[index].GetNullableInt16   (o); }
+		public override Int32?    GetNullableInt32   (object o, int index) { return this[index].GetNullableInt32   (o); }
+		public override Int64?    GetNullableInt64   (object o, int index) { return this[index].GetNullableInt64   (o); }
+
+		public override Byte?     GetNullableByte    (object o, int index) { return this[index].GetNullableByte    (o); }
+		[CLSCompliant(false)]
+		public override UInt16?   GetNullableUInt16  (object o, int index) { return this[index].GetNullableUInt16  (o); }
+		[CLSCompliant(false)]
+		public override UInt32?   GetNullableUInt32  (object o, int index) { return this[index].GetNullableUInt32  (o); }
+		[CLSCompliant(false)]
+		public override UInt64?   GetNullableUInt64  (object o, int index) { return this[index].GetNullableUInt64  (o); }
+
+		public override Boolean?  GetNullableBoolean (object o, int index) { return this[index].GetNullableBoolean (o); }
+		public override Char?     GetNullableChar    (object o, int index) { return this[index].GetNullableChar    (o); }
+		public override Single?   GetNullableSingle  (object o, int index) { return this[index].GetNullableSingle  (o); }
+		public override Double?   GetNullableDouble  (object o, int index) { return this[index].GetNullableDouble  (o); }
+		public override Decimal?  GetNullableDecimal (object o, int index) { return this[index].GetNullableDecimal (o); }
+		public override Guid?     GetNullableGuid    (object o, int index) { return this[index].GetNullableGuid    (o); }
+		public override DateTime? GetNullableDateTime(object o, int index) { return this[index].GetNullableDateTime(o); }
+		public override DateTimeOffset? GetNullableDateTimeOffset(object o, int index) { return this[index].GetNullableDateTimeOffset(o); }
+
+#if !SILVERLIGHT
+
+		// SQL type getters.
+		//
+		public override SqlByte     GetSqlByte    (object o, int index) { return this[index].GetSqlByte    (o); }
+		public override SqlInt16    GetSqlInt16   (object o, int index) { return this[index].GetSqlInt16   (o); }
+		public override SqlInt32    GetSqlInt32   (object o, int index) { return this[index].GetSqlInt32   (o); }
+		public override SqlInt64    GetSqlInt64   (object o, int index) { return this[index].GetSqlInt64   (o); }
+		public override SqlSingle   GetSqlSingle  (object o, int index) { return this[index].GetSqlSingle  (o); }
+		public override SqlBoolean  GetSqlBoolean (object o, int index) { return this[index].GetSqlBoolean (o); }
+		public override SqlDouble   GetSqlDouble  (object o, int index) { return this[index].GetSqlDouble  (o); }
+		public override SqlDateTime GetSqlDateTime(object o, int index) { return this[index].GetSqlDateTime(o); }
+		public override SqlDecimal  GetSqlDecimal (object o, int index) { return this[index].GetSqlDecimal (o); }
+		public override SqlMoney    GetSqlMoney   (object o, int index) { return this[index].GetSqlMoney   (o); }
+		public override SqlGuid     GetSqlGuid    (object o, int index) { return this[index].GetSqlGuid    (o); }
+		public override SqlString   GetSqlString  (object o, int index) { return this[index].GetSqlString  (o); }
+
+#endif
+
+		#endregion
+
+		#region IMapDataDestination Members
+
+		public override int GetOrdinal(string name)
+		{
+			MemberMapper mm;
+
+			lock (_nameToMember)
+				if (!_nameToMember.TryGetValue(name, out mm))
+					mm = this[name];
+
+			return mm == null? -1: mm.Ordinal;
+		}
+
+		public override void SetValue(object o, int index, object value)
+		{
+			_members[index].SetValue(o, value);
+		}
+
+		public override void SetValue(object o, string name, object value)
+		{
+			SetValue(o, GetOrdinal(name), value);
+		}
+
+		public override void SetNull    (object o, int index)                 { this[index].SetNull    (o); }
+
+		// Simple types setters.
+		//
+		[CLSCompliant(false)]
+		public override void SetSByte   (object o, int index, SByte    value) { this[index].SetSByte   (o, value); }
+		public override void SetInt16   (object o, int index, Int16    value) { this[index].SetInt16   (o, value); }
+		public override void SetInt32   (object o, int index, Int32    value) { this[index].SetInt32   (o, value); }
+		public override void SetInt64   (object o, int index, Int64    value) { this[index].SetInt64   (o, value); }
+
+		public override void SetByte    (object o, int index, Byte     value) { this[index].SetByte    (o, value); }
+		[CLSCompliant(false)]
+		public override void SetUInt16  (object o, int index, UInt16   value) { this[index].SetUInt16  (o, value); }
+		[CLSCompliant(false)]
+		public override void SetUInt32  (object o, int index, UInt32   value) { this[index].SetUInt32  (o, value); }
+		[CLSCompliant(false)]
+		public override void SetUInt64  (object o, int index, UInt64   value) { this[index].SetUInt64  (o, value); }
+
+		public override void SetBoolean (object o, int index, Boolean  value) { this[index].SetBoolean (o, value); }
+		public override void SetChar    (object o, int index, Char     value) { this[index].SetChar    (o, value); }
+		public override void SetSingle  (object o, int index, Single   value) { this[index].SetSingle  (o, value); }
+		public override void SetDouble  (object o, int index, Double   value) { this[index].SetDouble  (o, value); }
+		public override void SetDecimal (object o, int index, Decimal  value) { this[index].SetDecimal (o, value); }
+		public override void SetGuid    (object o, int index, Guid     value) { this[index].SetGuid    (o, value); }
+		public override void SetDateTime(object o, int index, DateTime value) { this[index].SetDateTime(o, value); }
+		public override void SetDateTimeOffset(object o, int index, DateTimeOffset value) { this[index].SetDateTimeOffset(o, value); }
+
+		// Simple types setters.
+		//
+		[CLSCompliant(false)]
+		public override void SetNullableSByte   (object o, int index, SByte?    value) { this[index].SetNullableSByte   (o, value); }
+		public override void SetNullableInt16   (object o, int index, Int16?    value) { this[index].SetNullableInt16   (o, value); }
+		public override void SetNullableInt32   (object o, int index, Int32?    value) { this[index].SetNullableInt32   (o, value); }
+		public override void SetNullableInt64   (object o, int index, Int64?    value) { this[index].SetNullableInt64   (o, value); }
+
+		public override void SetNullableByte    (object o, int index, Byte?     value) { this[index].SetNullableByte    (o, value); }
+		[CLSCompliant(false)]
+		public override void SetNullableUInt16  (object o, int index, UInt16?   value) { this[index].SetNullableUInt16  (o, value); }
+		[CLSCompliant(false)]
+		public override void SetNullableUInt32  (object o, int index, UInt32?   value) { this[index].SetNullableUInt32  (o, value); }
+		[CLSCompliant(false)]
+		public override void SetNullableUInt64  (object o, int index, UInt64?   value) { this[index].SetNullableUInt64  (o, value); }
+
+		public override void SetNullableBoolean (object o, int index, Boolean?  value) { this[index].SetNullableBoolean (o, value); }
+		public override void SetNullableChar    (object o, int index, Char?     value) { this[index].SetNullableChar    (o, value); }
+		public override void SetNullableSingle  (object o, int index, Single?   value) { this[index].SetNullableSingle  (o, value); }
+		public override void SetNullableDouble  (object o, int index, Double?   value) { this[index].SetNullableDouble  (o, value); }
+		public override void SetNullableDecimal (object o, int index, Decimal?  value) { this[index].SetNullableDecimal (o, value); }
+		public override void SetNullableGuid    (object o, int index, Guid?     value) { this[index].SetNullableGuid    (o, value); }
+		public override void SetNullableDateTime(object o, int index, DateTime? value) { this[index].SetNullableDateTime(o, value); }
+		public override void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value) { this[index].SetNullableDateTimeOffset(o, value); }
+
+#if !SILVERLIGHT
+
+		// SQL type setters.
+		//
+		public override void SetSqlByte    (object o, int index, SqlByte     value) { this[index].SetSqlByte    (o, value); }
+		public override void SetSqlInt16   (object o, int index, SqlInt16    value) { this[index].SetSqlInt16   (o, value); }
+		public override void SetSqlInt32   (object o, int index, SqlInt32    value) { this[index].SetSqlInt32   (o, value); }
+		public override void SetSqlInt64   (object o, int index, SqlInt64    value) { this[index].SetSqlInt64   (o, value); }
+		public override void SetSqlSingle  (object o, int index, SqlSingle   value) { this[index].SetSqlSingle  (o, value); }
+		public override void SetSqlBoolean (object o, int index, SqlBoolean  value) { this[index].SetSqlBoolean (o, value); }
+		public override void SetSqlDouble  (object o, int index, SqlDouble   value) { this[index].SetSqlDouble  (o, value); }
+		public override void SetSqlDateTime(object o, int index, SqlDateTime value) { this[index].SetSqlDateTime(o, value); }
+		public override void SetSqlDecimal (object o, int index, SqlDecimal  value) { this[index].SetSqlDecimal (o, value); }
+		public override void SetSqlMoney   (object o, int index, SqlMoney    value) { this[index].SetSqlMoney   (o, value); }
+		public override void SetSqlGuid    (object o, int index, SqlGuid     value) { this[index].SetSqlGuid    (o, value); }
+		public override void SetSqlString  (object o, int index, SqlString   value) { this[index].SetSqlString  (o, value); }
+
+#endif
+
+		#endregion
+
+		#region IEnumerable Members
+
+		public IEnumerator GetEnumerator()
+		{
+			return _members.GetEnumerator();
+		}
+
+		IEnumerator<MemberMapper> IEnumerable<MemberMapper>.GetEnumerator()
+		{
+			return _members.GetEnumerator();
+		}
+
+		#endregion
+	}
+}