using Dapper; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Mirle.Component.Database { /// /// Uses the Name value of the specified to determine /// the association between the name of the column in the query results and the member to /// which it will be extracted. If no column mapping is present all members are mapped as /// usual. /// /// The type of the object that this association between the mapper applies to. public class ColumnAttributeTypeMapper : FallbackTypeMapper { /// /// 建構式 /// public ColumnAttributeTypeMapper() : base(new SqlMapper.ITypeMap[] { new CustomPropertyTypeMap( typeof(T), (type, columnName) => type.GetProperties().ToList().Find(prop => prop.GetCustomAttributes(false) .OfType() .Any(attr => attr.Name == columnName) ) ), new DefaultTypeMap(typeof(T)) }) { } } /// /// 欄位屬性類別 /// [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class ColumnAttribute : Attribute { /// /// 欄位名稱 /// public string Name { get; set; } } /// /// 欄位成員對應類別 /// public class FallbackTypeMapper : SqlMapper.ITypeMap { private readonly IEnumerable _mappers; /// /// 建構式 /// /// public FallbackTypeMapper(IEnumerable mappers) { _mappers = mappers; } /// /// /// /// /// /// /// public ConstructorInfo FindConstructor(string[] names, Type[] types) { foreach (var mapper in _mappers) { try { ConstructorInfo result = mapper.FindConstructor(names, types); if (result != null) { return result; } } catch (NotImplementedException) { throw new NotImplementedException(); } } return null; } /// /// /// /// /// /// /// public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName) { foreach (var mapper in _mappers) { try { var result = mapper.GetConstructorParameter(constructor, columnName); if (result != null) { return result; } } catch (NotImplementedException) { throw new NotImplementedException(); } } return null; } /// /// /// /// /// /// public SqlMapper.IMemberMap GetMember(string columnName) { foreach (var mapper in _mappers) { try { var result = mapper.GetMember(columnName); if (result != null) { return result; } } catch (NotImplementedException) { throw new NotImplementedException(); } } return null; } /// /// /// /// public ConstructorInfo FindExplicitConstructor() { return _mappers .Select(mapper => mapper.FindExplicitConstructor()) .FirstOrDefault(result => result != null); } } }