Dapper prend désormais en charge des mappages personnalisés de colonnes vers des propriétés. Il le fait à travers l'interface ITypeMap. Une classe CustomPropertyTypeMap est fournie par Dapper, qui peut effectuer la plupart de ce travail. Par exemple:
Dapper.SqlMapper.SetTypeMap(
typeof(TModel),
new CustomPropertyTypeMap(
typeof(TModel),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType()
.Any(attr => attr.Name == columnName))));
Et le modèle:
public class TModel {
[Column(Name="my_property")]
public int MyProperty { get; set; }
}
Il est important de noter que l'implémentation de CustomPropertyTypeMap exige que l'attribut existe et corresponde à l'un des noms de colonne, sinon la propriété ne sera pas mappée. La classe DefaultTypeMap fournit la fonctionnalité standard et peut être exploitée pour modifier ce comportement:
public class FallbackTypeMapper : SqlMapper.ITypeMap
{
private readonly IEnumerable _mappers;
public FallbackTypeMapper(IEnumerable 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)
{
// la CustomPropertyTypeMap ne prend en charge qu'un constructeur sans arguments
// et lance une exception non implémentée. Pour contourner cela, attrapez et ignorez.
}
}
return null;
}
// implémenter d'autres méthodes d'interface de manière similaire
// requis parfois après la version 1.13 de dapper
public ConstructorInfo FindExplicitConstructor()
{
return _mappers
.Select(mapper => mapper.FindExplicitConstructor())
.FirstOrDefault(result => result != null);
}
}
Et avec cela en place, il devient facile de créer un mappage de type personnalisé qui utilisera automatiquement les attributs s'ils sont présents mais sinon, retournera au comportement standard:
public class ColumnAttributeTypeMapper : FallbackTypeMapper
{
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
}
}
Cela signifie que nous pouvons désormais facilement prendre en charge les types qui nécessitent un mappage à l'aide d'attributs:
Dapper.SqlMapper.SetTypeMap(
typeof(MyModel),
new ColumnAttributeTypeMapper());
Voici un Gist du code source complet.
0 votes
Possible duplicate de Dapper. Carte vers la colonne SQL avec des espaces dans les noms de colonnes