我有一个Person
类,其中包含一个通过访问Item
属性来延迟加载(自定义延迟加载)人员地址数据的属性。我希望它被映射到POCO类。怎么可能呢?
此外,只有在有数据(检查HasData
属性)并且如果没有数据时映射为null
,是否可以进行映射?
这些是源类:
public class SourcePerson
{
public string Name { get; set; }
public MyLazyLoadingObject<SourceAddress> Address;
}
public class SourceAddress
{
public string City { get; set; }
public string Country { get; set; }
}
这是自定义延迟加载类(简化):
public class MyLazyLoadingObject<T>
{
private int? _id;
private T _object;
public T Item
{
get
{
if (!_object.IsReaded)
{
_object.Read();
}
return _object;
}
}
public bool HasData
{
get
{
return _id.HasValue;
}
}
// Other non-relevant properties and methods
}
这些是目的地类:
public class DestinationPerson
{
public string Name { get; set; }
public DestinationAddress Address;
}
public class DestinationAddress
{
public string City { get; set; }
public string Country { get; set; }
}
答案 0 :(得分:2)
在没有代码重复的情况下,无法找到设置从MyLazyLoadingObject<T>
到T
然后T
到某些TDestination
的转换的传统方式。
但是使用一些手动表达式构建的自定义IObjectMapper
实现可以完成这项工作。
这是构建映射表达式的类:
public class MyLazyLoadingObjectMapper : IObjectMapper
{
public bool IsMatch(TypePair context)
{
return context.SourceType.IsGenericType && context.SourceType.GetGenericTypeDefinition() == typeof(MyLazyLoadingObject<>);
}
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
{
var item = Expression.Property(sourceExpression, "Item");
Expression result = item;
if (item.Type != destExpression.Type)
{
var typeMap = configurationProvider.ResolveTypeMap(item.Type, destExpression.Type);
result = Expression.Invoke(typeMap.MapExpression, item, destExpression, contextExpression);
}
// source != null && source.HasData ? result : default(TDestination)
return Expression.Condition(
Expression.AndAlso(
Expression.NotEqual(sourceExpression, Expression.Constant(null)),
Expression.Property(sourceExpression, "HasData")
),
result,
Expression.Default(destExpression.Type)
);
}
}
您只需将其注册到MapperRegistry
:
AutoMapper.Mappers.MapperRegistry.Mappers.Add(new MyLazyLoadingObjectMapper());
当然会创建常规类型地图(我猜你已经这样做了):
cfg.CreateMap<SourceAddress, DestinationAddress>();
cfg.CreateMap<SourcePerson, DestinationPerson>();
答案 1 :(得分:1)
我已经这样做了:
cfg.CreateMap<SourcePerson, DestinationPerson>().ForMember(t => t.Address, o => o.MapFrom(s => (s.Address.HasData)? s.Address.Item : null));