AutoMapper MapFrom 没有效果
AutoMapper MapFrom has no effect
已编辑:添加带有参数信息的构造函数。
我正在使用 AutoMapper 9.0 版和 .Net Core 2.1
以下单元测试应该更改 stockRecord.ClosePrice
的值,但如果存在第二个构造函数则不会。一旦注释掉第二个构造函数 closePrice
将具有正确的值 100.
股票记录Class
[DynamoDBTable("StockRecord")]
public class StockRecord
{
[DynamoDBHashKey]
public string TickerSymbol { get; set; }
[DynamoDBRangeKey]
public DateTime TradingDay { get; private set; }
public float OpenPrice { get; private set; }
public float ClosePrice { get; private set; }
public float DayHighestPrice { get; private set; }
public float DayLowestPrice { get; private set; }
public StockRecord() {}
// add this constructor below will make the unit test below fail, ClosePrice will stay value of 20
// Once Comment out this constructor, unit test will pass, ClosePrice value will change to 100
public StockRecord(string tickerSymbol, DateTime tradingDay, float openPrice, float closePrice, float dayHighestPrice, float dayLowestPrice)
{
TickerSymbol = tickerSymbol;
TradingDay = tradingDay;
OpenPrice = openPrice;
ClosePrice = closePrice;
DayHighestPrice = dayHighestPrice;
DayLowestPrice = dayLowestPrice;
}
}
StockRecordDto Class
public class StockRecordDto
{
public string TickerSymbol { get; set; }
public DateTime TradingDay { get; set; }
public float OpenPrice { get; set; }
public float ClosePrice { get; set; }
public float DayHighestPrice { get; set; }
public float DayLowestPrice { get; set; }
}
单元测试
[Fact]
public void Test1()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.ClosePrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForMember(dst => dst.ClosePrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
});
configuration.AssertConfigurationIsValid();
var mapper = configuration.CreateMapper();
var stockRecordDto = new StockRecordDto
{
TickerSymbol = "ticker 01",
TradingDay = DateTime.Now,
OpenPrice = 10,
ClosePrice = 20,
DayHighestPrice = 30,
DayLowestPrice = 5
};
StockRecord stockRecord = mapper.Map<StockRecord>(stockRecordDto);
Assert.Equal(100, stockRecord.ClosePrice);
}
根据 autoMapper 的文档,`stockRecord.ClosePrice 应该更改为 100。但它仍然是 20。
我花了整个下午,但仍然无法弄清楚。
我可以用工厂方法替换构造函数,但我仍然不明白为什么带参数的构造函数会出现问题。
如果这是一个错误,我将 post 在 AutoMapper 的 github 上提出一个问题。
谢谢。
如果您想更改 DayLowestPrice
,则在您的映射中使用 DayLowestPrice
作为目标字段而不是 ClosePrice
:
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
编辑:
由于您有一个带参数的构造函数,它被用来创建 StockRecord。因此,您可以通过 FromCtorParam
:
为构造函数成员显式指定映射
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForCtorParam("closePrice", op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
详细说明您的对象需要如何构建。您可以在 github.
上找到有关其行为为何如此的更多信息
编辑2:
您也可以使用 ConstructUsing
,但在这种情况下,您应该将属性设置为只读(从属性中删除 private set;
)并指定所有构造函数参数。在这种情况下,您可以避免硬编码构造函数参数名称。
public class StockRecord
{
***
public float ClosePrice { get; }
***
}
cfg.CreateMap<StockRecordDto, StockRecord>()
.ConstructUsing(s => new StockRecord(s.TickerSymbol, s.TradingDay, s.OpenPrice, s.ClosePrice > 0 ? 100 : 200, s.DayHighestPrice, s.DayLowestPrice));
已编辑:添加带有参数信息的构造函数。
我正在使用 AutoMapper 9.0 版和 .Net Core 2.1
以下单元测试应该更改 stockRecord.ClosePrice
的值,但如果存在第二个构造函数则不会。一旦注释掉第二个构造函数 closePrice
将具有正确的值 100.
股票记录Class
[DynamoDBTable("StockRecord")]
public class StockRecord
{
[DynamoDBHashKey]
public string TickerSymbol { get; set; }
[DynamoDBRangeKey]
public DateTime TradingDay { get; private set; }
public float OpenPrice { get; private set; }
public float ClosePrice { get; private set; }
public float DayHighestPrice { get; private set; }
public float DayLowestPrice { get; private set; }
public StockRecord() {}
// add this constructor below will make the unit test below fail, ClosePrice will stay value of 20
// Once Comment out this constructor, unit test will pass, ClosePrice value will change to 100
public StockRecord(string tickerSymbol, DateTime tradingDay, float openPrice, float closePrice, float dayHighestPrice, float dayLowestPrice)
{
TickerSymbol = tickerSymbol;
TradingDay = tradingDay;
OpenPrice = openPrice;
ClosePrice = closePrice;
DayHighestPrice = dayHighestPrice;
DayLowestPrice = dayLowestPrice;
}
}
StockRecordDto Class
public class StockRecordDto
{
public string TickerSymbol { get; set; }
public DateTime TradingDay { get; set; }
public float OpenPrice { get; set; }
public float ClosePrice { get; set; }
public float DayHighestPrice { get; set; }
public float DayLowestPrice { get; set; }
}
单元测试
[Fact]
public void Test1()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.ClosePrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForMember(dst => dst.ClosePrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
});
configuration.AssertConfigurationIsValid();
var mapper = configuration.CreateMapper();
var stockRecordDto = new StockRecordDto
{
TickerSymbol = "ticker 01",
TradingDay = DateTime.Now,
OpenPrice = 10,
ClosePrice = 20,
DayHighestPrice = 30,
DayLowestPrice = 5
};
StockRecord stockRecord = mapper.Map<StockRecord>(stockRecordDto);
Assert.Equal(100, stockRecord.ClosePrice);
}
根据 autoMapper 的文档,`stockRecord.ClosePrice 应该更改为 100。但它仍然是 20。 我花了整个下午,但仍然无法弄清楚。 我可以用工厂方法替换构造函数,但我仍然不明白为什么带参数的构造函数会出现问题。
如果这是一个错误,我将 post 在 AutoMapper 的 github 上提出一个问题。
谢谢。
如果您想更改 DayLowestPrice
,则在您的映射中使用 DayLowestPrice
作为目标字段而不是 ClosePrice
:
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
编辑:
由于您有一个带参数的构造函数,它被用来创建 StockRecord。因此,您可以通过 FromCtorParam
:
cfg.CreateMap<StockRecord, StockRecordDto>()
.ForMember(dst => dst.DayLowestPrice, op => op.MapFrom(src => src.ClosePrice > 0 ? 300 : 400))
.ReverseMap()
.ForCtorParam("closePrice", op => op.MapFrom(src => src.ClosePrice > 0 ? 100 : 200));
详细说明您的对象需要如何构建。您可以在 github.
上找到有关其行为为何如此的更多信息编辑2:
您也可以使用 ConstructUsing
,但在这种情况下,您应该将属性设置为只读(从属性中删除 private set;
)并指定所有构造函数参数。在这种情况下,您可以避免硬编码构造函数参数名称。
public class StockRecord
{
***
public float ClosePrice { get; }
***
}
cfg.CreateMap<StockRecordDto, StockRecord>()
.ConstructUsing(s => new StockRecord(s.TickerSymbol, s.TradingDay, s.OpenPrice, s.ClosePrice > 0 ? 100 : 200, s.DayHighestPrice, s.DayLowestPrice));