| 0 | 1 using System; | 
|  | 2 using System.Collections.Generic; | 
|  | 3 using System.Data; | 
|  | 4 using System.Linq; | 
|  | 5 using System.Linq.Expressions; | 
|  | 6 using System.Reflection; | 
|  | 7 | 
|  | 8 using BLToolkit.Data; | 
|  | 9 using BLToolkit.Data.DataProvider; | 
|  | 10 using BLToolkit.Reflection.Extension; | 
|  | 11 | 
|  | 12 namespace BLToolkit.Mapping.Fluent | 
|  | 13 { | 
|  | 14 	/// <summary> | 
|  | 15 	/// FluentSettings | 
|  | 16 	/// </summary> | 
|  | 17 	/// <typeparam name="T"></typeparam> | 
|  | 18 	public partial class FluentMap<T> | 
|  | 19 	{ | 
|  | 20 		private readonly TypeExtension _typeExtension; | 
|  | 21 		private List<IFluentMap> _childs; | 
|  | 22 		private const string MemberNameSeparator = "."; | 
|  | 23 | 
|  | 24 		/// <summary> | 
|  | 25 		/// ctor | 
|  | 26 		/// </summary> | 
|  | 27 		public FluentMap() | 
|  | 28 			: this(new TypeExtension { Name = typeof(T).FullName }, null) | 
|  | 29 		{ } | 
|  | 30 | 
|  | 31 		/// <summary> | 
|  | 32 		/// ctor | 
|  | 33 		/// </summary> | 
|  | 34 		/// <param name="typeExtension"></param> | 
|  | 35 		/// <param name="childs"></param> | 
|  | 36 		protected FluentMap(TypeExtension typeExtension, List<IFluentMap> childs) | 
|  | 37 		{ | 
|  | 38 			this._typeExtension = typeExtension; | 
|  | 39 			this._childs = childs; | 
|  | 40 | 
|  | 41             if (FluentConfig.MappingConfigurator.GetTableName != null) | 
|  | 42             { | 
|  | 43                 this.TableName(null, null, FluentConfig.MappingConfigurator.GetTableName(typeof(T))); | 
|  | 44             } | 
|  | 45 		} | 
|  | 46 | 
|  | 47 		/// <summary> | 
|  | 48 		/// TableNameAttribute | 
|  | 49 		/// </summary> | 
|  | 50 		/// <param name="name"></param> | 
|  | 51 		/// <returns></returns> | 
|  | 52 		public FluentMap<T> TableName(string name) | 
|  | 53 		{ | 
|  | 54 			return this.TableName(null, null, name); | 
|  | 55 		} | 
|  | 56 | 
|  | 57 		/// <summary> | 
|  | 58 		/// TableNameAttribute | 
|  | 59 		/// </summary> | 
|  | 60 		/// <param name="database"></param> | 
|  | 61 		/// <param name="name"></param> | 
|  | 62 		/// <returns></returns> | 
|  | 63 		public FluentMap<T> TableName(string database, string name) | 
|  | 64 		{ | 
|  | 65 			return this.TableName(database, null, name); | 
|  | 66 		} | 
|  | 67 | 
|  | 68 		/// <summary> | 
|  | 69 		/// TableNameAttribute | 
|  | 70 		/// </summary> | 
|  | 71 		/// <param name="database"></param> | 
|  | 72 		/// <param name="owner"></param> | 
|  | 73 		/// <param name="name"></param> | 
|  | 74 		/// <returns></returns> | 
|  | 75 		public FluentMap<T> TableName(string database, string owner, string name) | 
|  | 76 		{ | 
|  | 77 			((IFluentMap)this).TableName(database, owner, name); | 
|  | 78 			return this; | 
|  | 79 		} | 
|  | 80 | 
|  | 81 		/// <summary> | 
|  | 82 		/// MapFieldAttribute | 
|  | 83 		/// </summary> | 
|  | 84 		/// <typeparam name="TR"></typeparam> | 
|  | 85 		/// <param name="prop"></param> | 
|  | 86 		/// <param name="isInheritanceDiscriminator"></param> | 
|  | 87 		/// <returns></returns> | 
|  | 88 		public MapFieldMap<T,TR> MapField<TR>(Expression<Func<T, TR>> prop, bool isInheritanceDiscriminator) | 
|  | 89 		{ | 
|  | 90 			return this.MapField(prop, null, null, isInheritanceDiscriminator); | 
|  | 91 		} | 
|  | 92 | 
|  | 93 		/// <summary> | 
|  | 94 		/// MapFieldAttribute | 
|  | 95 		/// </summary> | 
|  | 96 		/// <typeparam name="TR"></typeparam> | 
|  | 97 		/// <param name="prop"></param> | 
|  | 98 		/// <param name="mapName"></param> | 
|  | 99 		/// <param name="storage"></param> | 
|  | 100 		/// <param name="isInheritanceDiscriminator"></param> | 
|  | 101 		/// <returns></returns> | 
|  | 102 		public MapFieldMap<T, TR> MapField<TR>(Expression<Func<T, TR>> prop, string mapName = null, string storage = null, bool? isInheritanceDiscriminator = null) | 
|  | 103 		{ | 
|  | 104 			string name = this.GetExprName(prop); | 
|  | 105 | 
|  | 106 			if (mapName == null && FluentConfig.MappingConfigurator.GetColumnName != null) | 
|  | 107 			{ | 
|  | 108 				mapName = FluentConfig.MappingConfigurator.GetColumnName(new MappedProperty { Name = name, Type = typeof(TR), ParentType = typeof(T) }); | 
|  | 109 			} | 
|  | 110 | 
|  | 111 			((IFluentMap)this).MapField(name, mapName, storage, isInheritanceDiscriminator); | 
|  | 112 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 113 		} | 
|  | 114 | 
|  | 115 		private void MapFieldOnType(string origName, string mapName) | 
|  | 116 		{ | 
|  | 117 			AttributeExtensionCollection attrs; | 
|  | 118 			if (!this._typeExtension.Attributes.TryGetValue(Attributes.MapField.Name, out attrs)) | 
|  | 119 			{ | 
|  | 120 				attrs = new AttributeExtensionCollection(); | 
|  | 121 				this._typeExtension.Attributes.Add(Attributes.MapField.Name, attrs); | 
|  | 122 			} | 
|  | 123 			var attributeExtension = new AttributeExtension(); | 
|  | 124 			attributeExtension.Values.Add(Attributes.MapField.OrigName, origName); | 
|  | 125             attributeExtension.Values.Add(Attributes.MapField.MapName, mapName); | 
|  | 126 			attrs.Add(attributeExtension); | 
|  | 127 		} | 
|  | 128 | 
|  | 129 		private void MapFieldOnField(string origName, string mapName, string storage, bool? isInheritanceDiscriminator) | 
|  | 130 		{ | 
|  | 131 			var member = this.GetMemberExtension(origName); | 
|  | 132 			if (!string.IsNullOrEmpty(mapName)) | 
|  | 133 			{ | 
|  | 134 				member.Attributes.Add(Attributes.MapField.Name, mapName); | 
|  | 135 			} | 
|  | 136 			if (null != storage) | 
|  | 137 			{ | 
|  | 138 				member.Attributes.Add(Attributes.MapField.Storage, storage); | 
|  | 139 			} | 
|  | 140 			if (null != isInheritanceDiscriminator) | 
|  | 141 			{ | 
|  | 142 				member.Attributes.Add(Attributes.MapField.IsInheritanceDiscriminator, this.ToString(isInheritanceDiscriminator.Value)); | 
|  | 143 			} | 
|  | 144 		} | 
|  | 145 | 
|  | 146 		/// <summary> | 
|  | 147 		/// PrimaryKeyAttribute | 
|  | 148 		/// </summary> | 
|  | 149 		/// <typeparam name="TR"></typeparam> | 
|  | 150 		/// <param name="prop"></param> | 
|  | 151 		/// <param name="order"></param> | 
|  | 152 		/// <returns></returns> | 
|  | 153 		public MapFieldMap<T, TR> PrimaryKey<TR>(Expression<Func<T, TR>> prop, int order = -1) | 
|  | 154 		{ | 
|  | 155 			string name = this.GetExprName(prop); | 
|  | 156 			((IFluentMap)this).PrimaryKey(name, order); | 
|  | 157 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 158 		} | 
|  | 159 | 
|  | 160 		/// <summary> | 
|  | 161 		/// NonUpdatableAttribute | 
|  | 162 		/// </summary> | 
|  | 163 		/// <returns></returns> | 
|  | 164 		public MapFieldMap<T, TR> NonUpdatable<TR>(Expression<Func<T, TR>> prop) | 
|  | 165 		{ | 
|  | 166 			string name = this.GetExprName(prop); | 
|  | 167 			((IFluentMap)this).NonUpdatable(name); | 
|  | 168 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 169 		} | 
|  | 170 | 
|  | 171 		/// <summary> | 
|  | 172 		/// IdentityAttribute | 
|  | 173 		/// </summary> | 
|  | 174 		/// <typeparam name="TR"></typeparam> | 
|  | 175 		/// <returns></returns> | 
|  | 176 		public MapFieldMap<T, TR> Identity<TR>(Expression<Func<T, TR>> prop) | 
|  | 177 		{ | 
|  | 178 			string name = this.GetExprName(prop); | 
|  | 179 			((IFluentMap)this).Identity(name); | 
|  | 180 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 181 		} | 
|  | 182 | 
|  | 183 		/// <summary> | 
|  | 184 		/// SqlIgnoreAttribute | 
|  | 185 		/// </summary> | 
|  | 186 		/// <param name="prop"></param> | 
|  | 187 		/// <param name="ignore"></param> | 
|  | 188 		/// <returns></returns> | 
|  | 189 		public MapFieldMap<T, TR> SqlIgnore<TR>(Expression<Func<T, TR>> prop, bool ignore = true) | 
|  | 190 		{ | 
|  | 191 			string name = this.GetExprName(prop); | 
|  | 192 			((IFluentMap)this).SqlIgnore(name, ignore); | 
|  | 193 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 194 		} | 
|  | 195 | 
|  | 196 		/// <summary> | 
|  | 197 		/// MapIgnoreAttribute | 
|  | 198 		/// </summary> | 
|  | 199 		/// <param name="prop"></param> | 
|  | 200 		/// <param name="ignore"></param> | 
|  | 201 		/// <returns></returns> | 
|  | 202 		public MapFieldMap<T, TR> MapIgnore<TR>(Expression<Func<T, TR>> prop, bool ignore = true) | 
|  | 203 		{ | 
|  | 204 			string name = this.GetExprName(prop); | 
|  | 205 			((IFluentMap)this).MapIgnore(name, ignore); | 
|  | 206 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 207 		} | 
|  | 208 | 
|  | 209 		/// <summary> | 
|  | 210 		/// TrimmableAttribute | 
|  | 211 		/// </summary> | 
|  | 212 		/// <returns></returns> | 
|  | 213 		public MapFieldMap<T, TR> Trimmable<TR>(Expression<Func<T, TR>> prop) | 
|  | 214 		{ | 
|  | 215 			string name = this.GetExprName(prop); | 
|  | 216 			((IFluentMap)this).Trimmable(name); | 
|  | 217 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 218 		} | 
|  | 219 | 
|  | 220 		/// <summary> | 
|  | 221 		/// MapValueAttribute | 
|  | 222 		/// </summary> | 
|  | 223 		/// <typeparam name="TV"> </typeparam> | 
|  | 224 		/// <typeparam name="TR"> </typeparam> | 
|  | 225 		/// <param name="prop"></param> | 
|  | 226 		/// <param name="origValue"></param> | 
|  | 227 		/// <param name="value"></param> | 
|  | 228 		/// <param name="values"></param> | 
|  | 229 		/// <returns></returns> | 
|  | 230 		public MapFieldMap<T, TR> MapValue<TV, TR>(Expression<Func<T, TR>> prop, TR origValue, TV value, params TV[] values) | 
|  | 231 		{ | 
|  | 232 			string name = this.GetExprName(prop); | 
|  | 233 			((IFluentMap)this).MapValue(name, origValue, value, values); | 
|  | 234 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 235 		} | 
|  | 236 | 
|  | 237 		/// <summary> | 
|  | 238 		/// DefaultValueAttribute | 
|  | 239 		/// </summary> | 
|  | 240 		/// <param name="prop"> </param> | 
|  | 241 		/// <param name="value"></param> | 
|  | 242 		/// <returns></returns> | 
|  | 243 		public MapFieldMap<T, TR> DefaultValue<TR>(Expression<Func<T, TR>> prop, TR value) | 
|  | 244 		{ | 
|  | 245 			string name = this.GetExprName(prop); | 
|  | 246 			((IFluentMap)this).DefaulValue(name, value); | 
|  | 247 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 248 		} | 
|  | 249 | 
|  | 250 		/// <summary> | 
|  | 251 		/// DbTypeAttribute | 
|  | 252 		/// </summary> | 
|  | 253 		/// <param name="prop"> </param> | 
|  | 254 		/// <param name="dbType"></param> | 
|  | 255 		/// <returns></returns> | 
|  | 256 		public MapFieldMap<T,TR> DbType<TR>(Expression<Func<T, TR>> prop, DbType dbType) | 
|  | 257 		{ | 
|  | 258 			string name = this.GetExprName(prop); | 
|  | 259 			((IFluentMap)this).DbType<TR>(name, dbType); | 
|  | 260 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 261 		} | 
|  | 262 | 
|  | 263 		/// <summary> | 
|  | 264 		/// MemberMapperAttribute | 
|  | 265 		/// </summary> | 
|  | 266 		/// <param name="prop"> </param> | 
|  | 267 		/// <param name="memberMapperType"></param> | 
|  | 268 		/// <returns></returns> | 
|  | 269 		public MapFieldMap<T,TR> MemberMapper<TR>(Expression<Func<T,TR>> prop, Type memberMapperType) | 
|  | 270 		{ | 
|  | 271 			return this.MemberMapper(prop, null, memberMapperType); | 
|  | 272 		} | 
|  | 273 | 
|  | 274 		/// <summary> | 
|  | 275 		/// MemberMapperAttribute | 
|  | 276 		/// </summary> | 
|  | 277 		/// <param name="prop"> </param> | 
|  | 278 		/// <param name="memberType"></param> | 
|  | 279 		/// <param name="memberMapperType"></param> | 
|  | 280 		/// <returns></returns> | 
|  | 281 		public MapFieldMap<T, TR> MemberMapper<TR>(Expression<Func<T, TR>> prop, Type memberType, Type memberMapperType) | 
|  | 282 		{ | 
|  | 283 			string name = this.GetExprName(prop); | 
|  | 284 			((IFluentMap)this).MemberMapper<TR>(name, memberType, memberMapperType); | 
|  | 285 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 286 		} | 
|  | 287 | 
|  | 288 		/// <summary> | 
|  | 289 		/// NullableAttribute | 
|  | 290 		/// </summary> | 
|  | 291 		/// <param name="prop"></param> | 
|  | 292 		/// <param name="isNullable"></param> | 
|  | 293 		/// <returns></returns> | 
|  | 294 		public MapFieldMap<T, TR> Nullable<TR>(Expression<Func<T, TR>> prop, bool isNullable = true) | 
|  | 295 		{ | 
|  | 296 			string name = this.GetExprName(prop); | 
|  | 297 			((IFluentMap)this).Nullable(name, isNullable); | 
|  | 298 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 299 		} | 
|  | 300 | 
|  | 301 		/// <summary> | 
|  | 302 		/// LazyInstanceAttribute | 
|  | 303 		/// </summary> | 
|  | 304 		/// <param name="prop"></param> | 
|  | 305 		/// <param name="isLazy"></param> | 
|  | 306 		/// <returns></returns> | 
|  | 307 		public MapFieldMap<T, TR> LazyInstance<TR>(Expression<Func<T, TR>> prop, bool isLazy = true) | 
|  | 308 		{ | 
|  | 309 			string name = this.GetExprName(prop); | 
|  | 310 			if (!GetIsVirtual(prop)) | 
|  | 311 				throw new Exception("Property wich uses LazyInstance needs to be virtual!"); | 
|  | 312 			((IFluentMap)this).LazyInstance(name, isLazy); | 
|  | 313 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 314 		} | 
|  | 315 | 
|  | 316 		/// <summary> | 
|  | 317 		/// NullValueAttribute | 
|  | 318 		/// </summary> | 
|  | 319 		/// <param name="prop"></param> | 
|  | 320 		/// <param name="value"></param> | 
|  | 321 		/// <returns></returns> | 
|  | 322 		public MapFieldMap<T, TR> NullValue<TR>(Expression<Func<T, TR>> prop, TR value) | 
|  | 323 		{ | 
|  | 324 			string name = this.GetExprName(prop); | 
|  | 325 			((IFluentMap)this).NullValue(name, value); | 
|  | 326 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 327 		} | 
|  | 328 | 
|  | 329 		/// <summary> | 
|  | 330 		/// AssociationAttribute | 
|  | 331 		/// </summary> | 
|  | 332 		/// <typeparam name="TRt"></typeparam> | 
|  | 333 		/// <typeparam name="TR"> </typeparam> | 
|  | 334 		/// <param name="prop"> </param> | 
|  | 335 		/// <param name="canBeNull"></param> | 
|  | 336 		/// <param name="thisKey"></param> | 
|  | 337 		/// <param name="thisKeys"></param> | 
|  | 338 		/// <returns></returns> | 
|  | 339 		public MapFieldMap<T, TR>.AssociationMap<TRt> Association<TRt, TR>(Expression<Func<T, TR>> prop, bool canBeNull, Expression<Func<T, TRt>> thisKey, params Expression<Func<T, TRt>>[] thisKeys) | 
|  | 340 		{ | 
|  | 341 			var keys = new List<Expression<Func<T, TRt>>>(thisKeys); | 
|  | 342 			keys.Insert(0, thisKey); | 
|  | 343 			return new MapFieldMap<T, TR>.AssociationMap<TRt>(new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop), canBeNull, keys); | 
|  | 344 		} | 
|  | 345 | 
|  | 346 		/// <summary> | 
|  | 347 		/// AssociationAttribute | 
|  | 348 		/// </summary> | 
|  | 349 		/// <typeparam name="TRt"></typeparam> | 
|  | 350 		/// <typeparam name="TR"> </typeparam> | 
|  | 351 		/// <param name="prop"> </param> | 
|  | 352 		/// <param name="thisKey"></param> | 
|  | 353 		/// <param name="thisKeys"></param> | 
|  | 354 		/// <returns></returns> | 
|  | 355 		public MapFieldMap<T, TR>.AssociationMap<TRt> Association<TRt, TR>(Expression<Func<T, TR>> prop, Expression<Func<T, TRt>> thisKey, params Expression<Func<T, TRt>>[] thisKeys) | 
|  | 356 		{ | 
|  | 357 			return this.Association(prop, true, thisKey, thisKeys); | 
|  | 358 		} | 
|  | 359 | 
|  | 360 		protected MapFieldMap<T, TR> Association<TRt, TR, TRf, TRo>(Expression<Func<T, TR>> prop, bool canBeNull | 
|  | 361 			, IEnumerable<Expression<Func<T, TRt>>> thisKeys, IEnumerable<Expression<Func<TRf, TRo>>> otherKeys) | 
|  | 362 		{ | 
|  | 363 			string name = this.GetExprName(prop); | 
|  | 364 			((IFluentMap)this).Association(name, canBeNull, this.KeysToString(thisKeys.ToArray()), this.KeysToString(otherKeys.ToArray())); | 
|  | 365 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 366 		} | 
|  | 367 | 
|  | 368 		/// <summary> | 
|  | 369 		/// Reverse on BLToolkit.Mapping.Association.ParseKeys() | 
|  | 370 		/// </summary> | 
|  | 371 		/// <typeparam name="T1"></typeparam> | 
|  | 372 		/// <typeparam name="T2"></typeparam> | 
|  | 373 		/// <param name="keys"></param> | 
|  | 374 		/// <returns></returns> | 
|  | 375 		private string KeysToString<T1, T2>(IEnumerable<Expression<Func<T1, T2>>> keys) | 
|  | 376 		{ | 
|  | 377 			return keys.Select(this.GetExprName).Aggregate((s1, s2) => s1 + ", " + s2); | 
|  | 378 		} | 
|  | 379 | 
|  | 380 		/// <summary> | 
|  | 381 		/// RelationAttribute | 
|  | 382 		/// </summary> | 
|  | 383 		/// <typeparam name="TR"></typeparam> | 
|  | 384 		/// <param name="prop"></param> | 
|  | 385 		/// <param name="slaveIndex"></param> | 
|  | 386 		/// <param name="masterIndex"></param> | 
|  | 387 		/// <returns></returns> | 
|  | 388 		public MapFieldMap<T, TR> Relation<TR>(Expression<Func<T, TR>> prop, string slaveIndex = null, string masterIndex = null) | 
|  | 389 		{ | 
|  | 390 			return this.Relation(prop, new[] { slaveIndex }, new[] { masterIndex }); | 
|  | 391 		} | 
|  | 392 | 
|  | 393 		/// <summary> | 
|  | 394 		/// RelationAttribute | 
|  | 395 		/// </summary> | 
|  | 396 		/// <typeparam name="TR"></typeparam> | 
|  | 397 		/// <param name="prop"></param> | 
|  | 398 		/// <param name="slaveIndex"></param> | 
|  | 399 		/// <param name="masterIndex"></param> | 
|  | 400 		/// <returns></returns> | 
|  | 401 		public MapFieldMap<T, TR> Relation<TR>(Expression<Func<T, TR>> prop, string[] slaveIndex, string[] masterIndex) | 
|  | 402 		{ | 
|  | 403 			string name = this.GetExprName(prop); | 
|  | 404 | 
|  | 405 			slaveIndex = (slaveIndex ?? new string[0]).Where(i => !string.IsNullOrEmpty(i)).ToArray(); | 
|  | 406 			masterIndex = (masterIndex ?? new string[0]).Where(i => !string.IsNullOrEmpty(i)).ToArray(); | 
|  | 407 | 
|  | 408 			Type destinationType = typeof(TR); | 
|  | 409 | 
|  | 410 			((IFluentMap)this).Relation(name, destinationType, slaveIndex, masterIndex); | 
|  | 411 			return new MapFieldMap<T, TR>(this._typeExtension, this.Childs, prop); | 
|  | 412 		} | 
|  | 413 | 
|  | 414 		static void FillRelationIndex(string[] index, AttributeExtension attributeExtension, string indexName) | 
|  | 415 		{ | 
|  | 416 			if (index.Any()) | 
|  | 417 			{ | 
|  | 418 				var collection = new AttributeExtensionCollection(); | 
|  | 419 				foreach (var s in index) | 
|  | 420 				{ | 
|  | 421 					var ae = new AttributeExtension(); | 
|  | 422 					ae.Values.Add(TypeExtension.AttrName.Name, s); | 
|  | 423 					collection.Add(ae); | 
|  | 424 				} | 
|  | 425 				attributeExtension.Attributes.Add(indexName, collection); | 
|  | 426 			} | 
|  | 427 		} | 
|  | 428 | 
|  | 429 		/// <summary> | 
|  | 430 		/// MapValueAttribute | 
|  | 431 		/// </summary> | 
|  | 432 		/// <typeparam name="TV"></typeparam> | 
|  | 433 		/// <param name="origValue"></param> | 
|  | 434 		/// <param name="value"></param> | 
|  | 435 		/// <param name="values"></param> | 
|  | 436 		/// <returns></returns> | 
|  | 437 		public FluentMap<T> MapValue<TV>(Enum origValue, TV value, params TV[] values) | 
|  | 438 		{ | 
|  | 439 			((IFluentMap)this).MapValue(origValue, value, values); | 
|  | 440 			return this; | 
|  | 441 		} | 
|  | 442 | 
|  | 443 		/// <summary> | 
|  | 444 		/// MapValueAttribute | 
|  | 445 		/// </summary> | 
|  | 446 		/// <typeparam name="TV"></typeparam> | 
|  | 447 		/// <param name="origValue"></param> | 
|  | 448 		/// <param name="value"></param> | 
|  | 449 		/// <param name="values"></param> | 
|  | 450 		/// <returns></returns> | 
|  | 451 		public FluentMap<T> MapValue<TV>(object origValue, TV value, params TV[] values) | 
|  | 452 		{ | 
|  | 453 			((IFluentMap)this).MapValue(origValue, value, values); | 
|  | 454 			return this; | 
|  | 455 		} | 
|  | 456 | 
|  | 457 		/// <summary> | 
|  | 458 		/// MapFieldAttribute(isInheritanceDescriminator = true) | 
|  | 459 		/// </summary> | 
|  | 460 		/// <typeparam name="TR"></typeparam> | 
|  | 461 		/// <param name="prop"></param> | 
|  | 462 		/// <returns></returns> | 
|  | 463 		public FluentMap<T> InheritanceField<TR>(Expression<Func<T, TR>> prop) | 
|  | 464 		{ | 
|  | 465 			return this.MapField(prop, true); | 
|  | 466 		} | 
|  | 467 | 
|  | 468 		/// <summary> | 
|  | 469 		/// InheritanceMappingAttribute | 
|  | 470 		/// </summary> | 
|  | 471 		/// <typeparam name="TC"></typeparam> | 
|  | 472 		/// <param name="code"></param> | 
|  | 473 		/// <returns></returns> | 
|  | 474 		public FluentMap<T> InheritanceMapping<TC>(object code) | 
|  | 475 		{ | 
|  | 476 			return this.InheritanceMapping<TC>(code, null); | 
|  | 477 		} | 
|  | 478 | 
|  | 479 		/// <summary> | 
|  | 480 		/// InheritanceMappingAttribute | 
|  | 481 		/// </summary> | 
|  | 482 		/// <typeparam name="TC"></typeparam> | 
|  | 483 		/// <param name="isDefault"></param> | 
|  | 484 		/// <returns></returns> | 
|  | 485 		public FluentMap<T> InheritanceMapping<TC>(bool isDefault) | 
|  | 486 		{ | 
|  | 487 			return this.InheritanceMapping<TC>(null, isDefault); | 
|  | 488 		} | 
|  | 489 | 
|  | 490 		/// <summary> | 
|  | 491 		/// InheritanceMappingAttribute | 
|  | 492 		/// </summary> | 
|  | 493 		/// <typeparam name="TC"></typeparam> | 
|  | 494 		/// <param name="code"></param> | 
|  | 495 		/// <param name="isDefault"></param> | 
|  | 496 		/// <returns></returns> | 
|  | 497 		public FluentMap<T> InheritanceMapping<TC>(object code, bool? isDefault) | 
|  | 498 		{ | 
|  | 499 			((IFluentMap)this).InheritanceMapping(typeof(TC), code, isDefault); | 
|  | 500 			return this; | 
|  | 501 		} | 
|  | 502 | 
|  | 503 		protected void FillMapValueExtension<TR, TV>(AttributeNameCollection attributeCollection, TR origValue, TV value, TV[] values) | 
|  | 504 		{ | 
|  | 505 			AttributeExtensionCollection list; | 
|  | 506 			if (!attributeCollection.TryGetValue(Attributes.MapValue.Name, out list)) | 
|  | 507 			{ | 
|  | 508 				list = new AttributeExtensionCollection(); | 
|  | 509 				attributeCollection.Add(Attributes.MapValue.Name, list); | 
|  | 510 			} | 
|  | 511 | 
|  | 512 			var allValues = new List<TV>(values); | 
|  | 513 			allValues.Insert(0, value); | 
|  | 514 			var tvFullName = typeof(TV).FullName; | 
|  | 515 | 
|  | 516 			foreach (var val in allValues) | 
|  | 517 			{ | 
|  | 518 				var attributeExtension = new AttributeExtension(); | 
|  | 519 				attributeExtension.Values.Add(Attributes.MapValue.OrigValue, origValue); | 
|  | 520 				attributeExtension.Values.Add(TypeExtension.ValueName.Value, Convert.ToString(val)); | 
|  | 521 				attributeExtension.Values.Add(TypeExtension.ValueName.Value + TypeExtension.ValueName.TypePostfix, tvFullName); | 
|  | 522 				list.Add(attributeExtension); | 
|  | 523 			} | 
|  | 524 		} | 
|  | 525 | 
|  | 526 		protected void FillMemberMapperExtension(AttributeNameCollection attributeCollection, Type memberType, Type memberMapperType) | 
|  | 527 		{ | 
|  | 528 			AttributeExtensionCollection attrs; | 
|  | 529 			if (!attributeCollection.TryGetValue(Attributes.MemberMapper.Name, out attrs)) | 
|  | 530 			{ | 
|  | 531 				attrs = new AttributeExtensionCollection(); | 
|  | 532 				attributeCollection.Add(Attributes.MemberMapper.Name, attrs); | 
|  | 533 			} | 
|  | 534 			var attributeExtension = new AttributeExtension(); | 
|  | 535 			attributeExtension.Values.Add(Attributes.MemberMapper.MemberType, memberType); | 
|  | 536 			attributeExtension.Values.Add(Attributes.MemberMapper.MemberMapperType, memberMapperType); | 
|  | 537 			attrs.Add(attributeExtension); | 
|  | 538 		} | 
|  | 539 | 
|  | 540 		/// <summary> | 
|  | 541 		/// Fluent settings result | 
|  | 542 		/// </summary> | 
|  | 543 		/// <returns></returns> | 
|  | 544 		public ExtensionList Map() | 
|  | 545 		{ | 
|  | 546 			var result = new ExtensionList(); | 
|  | 547 			this.MapTo(result); | 
|  | 548 			return result; | 
|  | 549 		} | 
|  | 550 | 
|  | 551 		/// <summary> | 
|  | 552 		/// Apply fluent settings to DbManager | 
|  | 553 		/// </summary> | 
|  | 554 		/// <param name="dbManager"></param> | 
|  | 555 		public void MapTo(DbManager dbManager) | 
|  | 556 		{ | 
|  | 557 			var ms = dbManager.MappingSchema ?? (dbManager.MappingSchema = Mapping.Map.DefaultSchema); | 
|  | 558 			this.MapTo(ms); | 
|  | 559 		} | 
|  | 560 | 
|  | 561 		/// <summary> | 
|  | 562 		/// Apply fluent settings to DataProviderBase | 
|  | 563 		/// </summary> | 
|  | 564 		/// <param name="dataProvider"></param> | 
|  | 565 		public void MapTo(DataProviderBase dataProvider) | 
|  | 566 		{ | 
|  | 567 			var ms = dataProvider.MappingSchema ?? (dataProvider.MappingSchema = Mapping.Map.DefaultSchema); | 
|  | 568 			this.MapTo(ms); | 
|  | 569 		} | 
|  | 570 | 
|  | 571 		/// <summary> | 
|  | 572 		/// Apply fluent settings to MappingSchema | 
|  | 573 		/// </summary> | 
|  | 574 		/// <param name="mappingSchema"></param> | 
|  | 575 		public void MapTo(MappingSchema mappingSchema) | 
|  | 576 		{ | 
|  | 577 			var extensions = mappingSchema.Extensions ?? (mappingSchema.Extensions = new ExtensionList()); | 
|  | 578 			this.MapTo(extensions); | 
|  | 579 		} | 
|  | 580 | 
|  | 581 		/// <summary> | 
|  | 582 		/// Apply fluent settings to ExtensionList | 
|  | 583 		/// </summary> | 
|  | 584 		/// <param name="extensions"></param> | 
|  | 585 		public void MapTo(ExtensionList extensions) | 
|  | 586 		{ | 
|  | 587 			var ext = this._typeExtension; | 
|  | 588 			TypeExtension oldExt; | 
|  | 589 			if (extensions.TryGetValue(ext.Name, out oldExt)) | 
|  | 590 			{ | 
|  | 591 				FluentMapHelper.MergeExtensions(ext, ref oldExt); | 
|  | 592 			} | 
|  | 593 			else | 
|  | 594 			{ | 
|  | 595 				extensions.Add(ext); | 
|  | 596 			} | 
|  | 597 			this.EachChilds(m => m.MapTo(extensions)); | 
|  | 598 		} | 
|  | 599 | 
|  | 600 		protected MemberExtension GetMemberExtension<TR>(Expression<Func<T, TR>> prop) | 
|  | 601 		{ | 
|  | 602 			string name = this.GetExprName(prop); | 
|  | 603 			return this.GetMemberExtension(name); | 
|  | 604 		} | 
|  | 605 | 
|  | 606 		protected MemberExtension GetMemberExtension(string name) | 
|  | 607 		{ | 
|  | 608 			MemberExtension member; | 
|  | 609 			if (!this._typeExtension.Members.TryGetValue(name, out member)) | 
|  | 610 			{ | 
|  | 611 				member = new MemberExtension { Name = name }; | 
|  | 612 				this._typeExtension.Members.Add(member); | 
|  | 613 			} | 
|  | 614 			return member; | 
|  | 615 		} | 
|  | 616 | 
|  | 617 		private string GetExprName<TT, TR>(Expression<Func<TT, TR>> prop) | 
|  | 618 		{ | 
|  | 619 			string result = null; | 
|  | 620 			var memberExpression = prop.Body as MemberExpression; | 
|  | 621 			while (null != memberExpression) | 
|  | 622 			{ | 
|  | 623 				result = null == result ? "" : MemberNameSeparator + result; | 
|  | 624 				result = memberExpression.Member.Name + result; | 
|  | 625 				memberExpression = memberExpression.Expression as MemberExpression; | 
|  | 626 			} | 
|  | 627 			if (null == result) | 
|  | 628 			{ | 
|  | 629 				throw new ArgumentException("Fail member access expression."); | 
|  | 630 			} | 
|  | 631 			return result; | 
|  | 632 		} | 
|  | 633 | 
|  | 634 		static bool GetIsVirtual<TT, TR>(Expression<Func<TT, TR>> prop) | 
|  | 635 		{ | 
|  | 636 			var memberExpression = prop.Body as MemberExpression; | 
|  | 637 			if (memberExpression != null) | 
|  | 638 			{ | 
|  | 639 				var prpInfo = memberExpression.Member as PropertyInfo; | 
|  | 640 				if (prpInfo != null && !prpInfo.GetGetMethod().IsVirtual) | 
|  | 641 				{ | 
|  | 642 					return false; | 
|  | 643 				} | 
|  | 644 			} | 
|  | 645 | 
|  | 646 			return true; | 
|  | 647 		} | 
|  | 648 | 
|  | 649 		/// <summary> | 
|  | 650 		/// Invert for BLToolkit.Reflection.Extension.TypeExtension.ToBoolean() | 
|  | 651 		/// </summary> | 
|  | 652 		/// <param name="value"></param> | 
|  | 653 		/// <returns></returns> | 
|  | 654 		protected string ToString(bool value) | 
|  | 655 		{ | 
|  | 656 			return Convert.ToString(value); | 
|  | 657 		} | 
|  | 658 | 
|  | 659 		private void EachChilds(Action<IFluentMap> action) | 
|  | 660 		{ | 
|  | 661 			foreach (var childMap in this.Childs) | 
|  | 662 			{ | 
|  | 663 				action(childMap); | 
|  | 664 			} | 
|  | 665 		} | 
|  | 666 | 
|  | 667 		private List<IFluentMap> Childs | 
|  | 668 		{ | 
|  | 669 			get | 
|  | 670 			{ | 
|  | 671 				if (null == this._childs) | 
|  | 672 				{ | 
|  | 673 					this._childs = new List<IFluentMap>(); | 
|  | 674 					var thisType = typeof(T); | 
|  | 675 					var fmType = typeof(FluentMap<>); | 
|  | 676 					// Find child only first generation ... other generation find recursive | 
|  | 677 					foreach (var childType in thisType.Assembly.GetTypes().Where(t => t.BaseType == thisType)) | 
|  | 678 					{ | 
|  | 679 						this._childs.Add((IFluentMap)Activator.CreateInstance(fmType.MakeGenericType(childType))); | 
|  | 680 					} | 
|  | 681 				} | 
|  | 682 				return this._childs; | 
|  | 683 			} | 
|  | 684 		} | 
|  | 685 	} | 
|  | 686 } |