自动包装类

时间:2012-01-27 15:01:18

标签: automapper

我们希望从一个数据库的context.tableType一般映射到另一个 例如UatDb.Branch - LiveDb.Branch

表格相同,因此不需要MapFrom。

以下通用映射定义就足够了

Mapper.CreateMap<TFromContextTableType,TToContextTableType>();

然而!!!

我们需要在以下包装类中包装源context.tableType:

public class SWrapper<TFrom> where TFrom : class
{
        public SWrapper(TFrom model)
        {
            Model = model;
        }
        public TFrom Model { get; private set; }
}

现在要执行映射,我们必须映射如下:

Mapper.CreateMap<SWrapper<FromBranchType>, ToBranchType>().ConstructUsing(x => new        Live.Branch()))
.ForMember(d => d.BranchID, o => o.MapFrom(x => x.Model.BranchID))
.ForMember(d => d.BranchName, o => o.MapFrom(x => x.Model.BranchName))
.ForMember(d => d.BranchCountry, o => o.MapFrom(x => x.Model.BranchCountry))

这意味着我们不能一般地映射并且必须为每个映射显式声明ForMember。我无法找出使用旋转变压器或类型转换器的任何解决方案。

我想过可能将目标包装在SWrapper中然后解析返回的Wrapped对象以返回内部Product但不知道如何执行此操作。

欢迎所有想法......

2 个答案:

答案 0 :(得分:1)

从您的映射中获取您可以执行以下操作,而不需要您手动输入所有属性映射。第二个测试中的辅助方法允许您可能不需要的专门映射。

[TestMethod]
public void Given_a_wrapper_class_I_should_be_able_to_unwrap_it_and_continue_with_mappings()
{
    Mapper.CreateMap<Wrapper<Source>, Destination>()
          .UnwrapUsing<Wrapper<Source>, Source, Destination>(w => w.Model)
          .ForMember(d => d.Bar, o => o.MapFrom(d => d.Baz));

    var source = new Source { Baz = 1, Foo = "One" };
    var wrapped = new Wrapper<Source> { Model = source };
    var destination = Mapper.Map<Destination>(wrapped);

    Assert.IsNotNull(destination);
    Assert.AreEqual(1, destination.Bar);
    Assert.AreEqual("One", destination.Foo);
}

public static class AutoMapperExtensions
{
    public static IMappingExpression<TSource, TDest> UnwrapUsing<TWrapper, TSource, TDest>(this IMappingExpression<TWrapper, TDest> expr, Func<Wrapper<TSource>, TSource> unwrapper)
    {
        Mapper.CreateMap<Wrapper<TSource>, TDest>()
              .ConstructUsing(x => Mapper.Map<TSource, TDest>(unwrapper(x)));

        return Mapper.CreateMap<TSource, TDest>();
    }
}

public class Source
{
    public string Foo { get; set; }
    public int Baz { get; set; }
}

public class Destination
{
    public string Foo { get; set; }
    public int Bar { get; set; }
}

public class Wrapper<T>
{
    public T Model { get; set; }
}

答案 1 :(得分:0)

如何在您的包装类中添加一个小实用程序方法:

public TDest MapTo<TDest>()
{
    return Mapper.Map<TFrom, TDest>(this.Model);
}