using System.Numerics; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace DapperExtensions.Mapper { public interface IClassMapper { string SchemaName { get; } string TableName { get; } IList Properties { get; } Type EntityType { get; } } public interface IClassMapper : IClassMapper where T : class { } /// /// Maps an entity to a table through a collection of property maps. /// public class ClassMapper : IClassMapper where T : class { /// /// Gets or sets the schema to use when referring to the corresponding table name in the database. /// public string SchemaName { get; protected set; } /// /// Gets or sets the table to use in the database. /// public string TableName { get; protected set; } /// /// A collection of properties that will map to columns in the database table. /// public IList Properties { get; private set; } public Type EntityType { get { return typeof(T); } } public ClassMapper() { PropertyTypeKeyTypeMapping = new Dictionary { { typeof(byte), KeyType.Identity }, { typeof(byte?), KeyType.Identity }, { typeof(sbyte), KeyType.Identity }, { typeof(sbyte?), KeyType.Identity }, { typeof(short), KeyType.Identity }, { typeof(short?), KeyType.Identity }, { typeof(ushort), KeyType.Identity }, { typeof(ushort?), KeyType.Identity }, { typeof(int), KeyType.Identity }, { typeof(int?), KeyType.Identity }, { typeof(uint), KeyType.Identity}, { typeof(uint?), KeyType.Identity }, { typeof(long), KeyType.Identity }, { typeof(long?), KeyType.Identity }, { typeof(ulong), KeyType.Identity }, { typeof(ulong?), KeyType.Identity }, { typeof(BigInteger), KeyType.Identity }, { typeof(BigInteger?), KeyType.Identity }, { typeof(Guid), KeyType.Guid }, { typeof(Guid?), KeyType.Guid }, }; Properties = new List(); Table(typeof(T).Name); } protected Dictionary PropertyTypeKeyTypeMapping { get; private set; } public virtual void Schema(string schemaName) { SchemaName = schemaName; } public virtual void Table(string tableName) { TableName = tableName; } protected virtual void AutoMap() { AutoMap(null); } protected virtual void AutoMap(Func canMap) { Type type = typeof(T); bool hasDefinedKey = Properties.Any(p => p.KeyType != KeyType.NotAKey); PropertyMap keyMap = null; foreach (var propertyInfo in type.GetProperties()) { if (Properties.Any(p => p.Name.Equals(propertyInfo.Name, StringComparison.CurrentCultureIgnoreCase))) { continue; } if ((canMap != null && !canMap(type, propertyInfo))) { continue; } PropertyMap map = Map(propertyInfo); if (!hasDefinedKey) { if (string.Equals(map.PropertyInfo.Name, "id", StringComparison.CurrentCultureIgnoreCase)) { keyMap = map; } // if (keyMap == null && map.PropertyInfo.Name.EndsWith("id", true, CultureInfo.InvariantCulture)) if (keyMap == null && map.PropertyInfo.Name.EndsWith("id", StringComparison.CurrentCultureIgnoreCase)) { keyMap = map; } } } if (keyMap != null) { keyMap.Key(PropertyTypeKeyTypeMapping.ContainsKey(keyMap.PropertyInfo.PropertyType) ? PropertyTypeKeyTypeMapping[keyMap.PropertyInfo.PropertyType] : KeyType.Assigned); } } /// /// Fluently, maps an entity property to a column /// protected PropertyMap Map(Expression> expression) { PropertyInfo propertyInfo = ReflectionHelper.GetProperty(expression) as PropertyInfo; return Map(propertyInfo); } /// /// Fluently, maps an entity property to a column /// protected PropertyMap Map(PropertyInfo propertyInfo) { PropertyMap result = new PropertyMap(propertyInfo); this.GuardForDuplicatePropertyMap(result); Properties.Add(result); return result; } private void GuardForDuplicatePropertyMap(PropertyMap result) { if (Properties.Any(p => p.Name.Equals(result.Name))) { throw new ArgumentException(string.Format("Duplicate mapping for property {0} detected.",result.Name)); } } } }