You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.8 KiB
151 lines
4.8 KiB
using Dapper;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace Mirle.Component.Database
|
|
{
|
|
/// <summary>
|
|
/// Uses the Name value of the <see cref="ColumnAttribute"/> 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.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of the object that this association between the mapper applies to.</typeparam>
|
|
public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
|
|
{
|
|
/// <summary>
|
|
/// 建構式
|
|
/// </summary>
|
|
public ColumnAttributeTypeMapper()
|
|
: base(new SqlMapper.ITypeMap[]
|
|
{
|
|
new CustomPropertyTypeMap(
|
|
typeof(T),
|
|
(type, columnName) =>
|
|
type.GetProperties().ToList().Find(prop =>
|
|
prop.GetCustomAttributes(false)
|
|
.OfType<ColumnAttribute>()
|
|
.Any(attr => attr.Name == columnName)
|
|
)
|
|
),
|
|
new DefaultTypeMap(typeof(T))
|
|
})
|
|
{
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 欄位屬性類別
|
|
/// </summary>
|
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
|
public class ColumnAttribute : Attribute
|
|
{
|
|
/// <summary>
|
|
/// 欄位名稱
|
|
/// </summary>
|
|
public string Name { get; set; }
|
|
}
|
|
/// <summary>
|
|
/// 欄位成員對應類別
|
|
/// </summary>
|
|
public class FallbackTypeMapper : SqlMapper.ITypeMap
|
|
{
|
|
private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;
|
|
/// <summary>
|
|
/// 建構式
|
|
/// </summary>
|
|
/// <param name="mappers"></param>
|
|
public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
|
|
{
|
|
_mappers = mappers;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="names"></param>
|
|
/// <param name="types"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="constructor"></param>
|
|
/// <param name="columnName"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="columnName"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public ConstructorInfo FindExplicitConstructor()
|
|
{
|
|
return _mappers
|
|
.Select(mapper => mapper.FindExplicitConstructor())
|
|
.FirstOrDefault(result => result != null);
|
|
}
|
|
}
|
|
}
|