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;
どこが間違っているのか教えてください