我有一个场景,我正在创建一个映射实用程序,通过它我们可以映射DataReader
到实体。
Mapper.CreateMap<IDataReader, T>();
List<T> tList = Mapper.Map<List<T>>(reader);
return tList;
如果实体具有与存储过程输出中相同的列,则此方法可以正常工作。但是,我正在处理一些列名不匹配的旧代码。所以我创建了一个属性,通过它我可以从 sprocs 中指定相应的列。我使用这样的代码指定它们
[DBColumn('EmployeeName')]
public string EmpName { get; set; }
有什么方法可以使用泛型/反射来实现这一点?请注意,我有多个这样的实例,并且正在构建一个实用程序。所以我不能使用ForMember
方法来实现这一点。
更新:我尝试创建这样的自定义转换器。但是,我的转换函数根本没有被调用。
自定义转换器
public class CustomConverter<T> : ITypeConverter<System.Data.IDataReader, T>
{
private ResolutionContext _Context = null;
private Dictionary<string, string> _CustomProps { get; set; }
public T Convert(ResolutionContext context)
{
_Context = context;
if (_Context.SourceValue != null &&
!(_Context.SourceValue is System.Data.IDataReader))
{
string message = "Value supplied is of type {0} but expected {1}.\n" +
"Change the type converter source type, or redirect " +
"the source value supplied to the value resolver using FromMember.";
throw new AutoMapperMappingException(_Context, string.Format(
message, typeof(System.Data.IDataReader), _Context.SourceValue.GetType()));
}
_CustomProps = new Dictionary<string, string>();
foreach (PropertyInfo propInfo in context.DestinationType.GetProperties())
{
if (propInfo.CustomAttributes.Any(attr => attr.AttributeType == typeof(DBColumn)))
{
DBColumn propertyValue = (DBColumn)propInfo.GetCustomAttribute(typeof(DBColumn));
_CustomProps.Add(propertyValue.ColumnName, propInfo.Name);
}
}
//return base.Convert(context);
return ConvertCore((System.Data.IDataReader)context.SourceValue);
}
protected T ExistingDestination
{
get
{
if (_Context == null)
{
string message = "ResolutionContext is not yet set. " +
"Only call this property inside the 'ConvertCore' method.";
throw new InvalidOperationException(message);
}
if (_Context.DestinationValue != null &&
!(_Context.DestinationValue is T))
{
string message = "Destination Value is of type {0} but expected {1}.";
throw new AutoMapperMappingException(_Context, string.Format(
message, typeof(T), _Context.DestinationValue.GetType()));
}
return (T)_Context.DestinationValue;
}
}
protected T ConvertCore(System.Data.IDataReader source)
{
T obj = ExistingDestination;
if (obj != null)
{
foreach (KeyValuePair<string, string> keyValuePair in _CustomProps)
{
PropertyInfo prop = obj.GetType().GetProperty(keyValuePair.Key, BindingFlags.Public | BindingFlags.Instance);
if (null != prop && prop.CanWrite)
{
prop.SetValue(obj, System.Convert.ChangeType(source[keyValuePair.Value], prop.PropertyType));
}
}
}
return obj;
}
我指定在下面的语句中使用这个 CustomConverter。
Mapper.CreateMap<IDataReader, T>().ConvertUsing<CustomConverter<T>>();
List<T> tList = Mapper.Map<List<T>>(reader);
return tList;
请让我知道我哪里出错了