我创建了一个域实体,所有的设置方法都是私有的,因为它们在设置数据之前有一些验证。
所以我有Dtos来交换数据,然后我把它映射到实体上,这样如果一切顺利的话,我就可以持久化到数据库中。
当把Dto映射到Entity时,我得到的Entity的所有属性都被填满了,但是SetXXX没有被执行,如果我直接调用构造函数就会发生这种情况。
当使用AutoMapper时,对于这些情况,最好或正确的方法是什么?
域实体
public Product(Guid id, ... decimal originalPrice, decimal discountedPrice...) :
base(id)
{
OriginalPrice = CheckOriginalPrice(originalPrice, discountedPrice);
DiscountedPrice = CheckDiscountedPrice(originalPrice, discountedPrice);
}
public virtual void SetOriginalPrice(decimal originalPrice, decimal discountedPrice)
{
OriginalPrice = CheckOriginalPrice(originalPrice, discountedPrice);
}
private static decimal CheckOriginalPrice(decimal originalPrice, decimal discountedPrice)
{
if (originalPrice < 0)
throw new ArgumentOutOfRangeException($"original price ({originalPrice} cannot be negative");
else if (originalPrice < discountedPrice)
throw new ArgumentOutOfRangeException($"original price ({originalPrice}) can not be lower than discounted price ({discountedPrice})!");
return originalPrice;
}
如果我这样做,Map会成功,所以没有发生验证,如何触发构造函数?
var product = _objectMapper.Map<CreateProductDto, Product>(product);
如果我直接测试实体类,它通过了测试,因为价格被检查,我得到了异常。
var exception = await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () =>
{
//Act
var product =
new Product(
_guidGenerator.Create(),
...
4.05m,
8.05m,
...
);
});
//Assert
exception.Message.ShouldContain("original price");
那么,我如何实现在使用ObjetMapper.Map进行映射时,构造函数将被正确执行,是否有一个简单的方法来实现它?
AutoMapper有一个叫做条件映射的功能,这似乎就是你要找的东西。https:/docs.automapper.orgenstableConditional-mapping.html。
实际上,我设法解决了我的问题,有一个与我的dto参数相同的构造函数,这样AutoMapper可以直接使用正确的构造函数。