Dapper hiện hỗ trợ cột tùy chỉnh cho người lập bản đồ tài sản. Nó làm như vậy thông qua giao diện ITypeMap . Một lớp CustomPropertyTypeMap được cung cấp bởi Dapper có thể thực hiện hầu hết công việc này. Ví dụ:
Dapper.SqlMapper.SetTypeMap(
typeof(TModel),
new CustomPropertyTypeMap(
typeof(TModel),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName))));
Và mô hình:
public class TModel {
[Column(Name="my_property")]
public int MyProperty { get; set; }
}
Điều quan trọng cần lưu ý là việc triển khai CustomPropertyTypeMap yêu cầu thuộc tính tồn tại và khớp với một trong các tên cột hoặc thuộc tính sẽ không được ánh xạ. Lớp DefaultTypeMap cung cấp chức năng tiêu chuẩn và có thể được tận dụng để thay đổi hành vi này:
public class FallbackTypeMapper : SqlMapper.ITypeMap
{
private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;
public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
{
_mappers = mappers;
}
public SqlMapper.IMemberMap GetMember(string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetMember(columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException nix)
{
// the CustomPropertyTypeMap only supports a no-args
// constructor and throws a not implemented exception.
// to work around that, catch and ignore.
}
}
return null;
}
// implement other interface methods similarly
// required sometime after version 1.13 of dapper
public ConstructorInfo FindExplicitConstructor()
{
return _mappers
.Select(mapper => mapper.FindExplicitConstructor())
.FirstOrDefault(result => result != null);
}
}
Và với điều đó, việc tạo một trình ánh xạ loại tùy chỉnh sẽ tự động sử dụng các thuộc tính nếu chúng có mặt nhưng sẽ trở lại hành vi tiêu chuẩn trở nên dễ dàng hơn:
public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
}
}
Điều đó có nghĩa là bây giờ chúng ta có thể dễ dàng hỗ trợ các loại yêu cầu bản đồ bằng các thuộc tính:
Dapper.SqlMapper.SetTypeMap(
typeof(MyModel),
new ColumnAttributeTypeMapper<MyModel>());
Đây là một ý chính cho mã nguồn đầy đủ .