使用automapper将域模型映射到逻辑模型

时间:2016-05-11 15:44:49

标签: asp.net mapping automapper

我的问题是在使用Automapper将域模型映射到逻辑模型时使用循环导航属性。

以下是域模型的示例:

public class Customer
{
    public long CustomerId { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<Payment> Payments { get; set; }      
}

public class Payment
{
    public long PaymentId { get; set; }

    public virtual Customer Customer { get; set; }
}

这里是逻辑模型:

public class CustomerModel
{
    public long CustomerId { get; set; }

    public string Name { get; set; }

    public IEnumerable<PaymentModel> Payments { get; set; }
}

public class PaymentModel
{
    public long PaymentId { get; set; }

    public CustomerModel Customer { get; set; }
}

现在。当我使用automapper执行映射时:

public IQueryable<CustomerModel> GetCustomers()
{
    return _db.Customer.ProjectTo<CustomerModel>();
}

}

我收到System.StackOverflowException。据我了解,因为导航循环。将Customer映射到CustomerModel后,Automapper尝试将ICollection付款映射到IEnumerable付款,但由于导航到PaymentModel类内的CustomerModel,其循环... 我知道我可以通过创建第二个逻辑模型(类Payment2)来修复它,而不需要导航属性到CustomerModel,但我必须执行另一个映射。有50个具有导航属性的域模型,它会很烦人。

还有其他更简单快捷的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我建议更改Payments属性的类型:

public class CustomerModel
{
    public List<PaymentModel> Payments { get; set; }
}

并手动映射:

Mapper.CreateMap<Payment, PaymentModel>()
    .ForMember(dest => dest.Customer, opt => opt.Ignore());
Mapper.CreateMap<Customer, CustomerModel>()
    .AfterMap((src, dest) => dest.Payments.ForEach(p => p.Customer = dest));

编辑:不幸的是,只有在从Customer实体开始映射的情况下它才会起作用:

CustomerModel model = Mapper.Map<CustomerModel>(entity); 

如果您不关心性能,请尝试DynamicMap

CustomerModel model = Mapper.DynamicMap<CustomerModel>(entity);