自动映射器 - > DTO 到实体 - 如何在映射时触发 Setter 验证



我创建了一个域实体,所有的set方法都是私有的,因为它们在设置数据之前有一些验证。

因此,我有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;
}

如果我这样做,映射会成功,所以没有验证,如何触发构造函数?

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.org/en/stable/Conditional-mapping.html

实际上,我通过拥有一个与我的dto具有相同参数的构造函数来解决我的问题,这样AutoMapper就可以直接使用正确的构造函数。

相关内容

最新更新