我正在尝试将我的 MVC3 项目分成适当的 DAL/Domain/ViewModel 架构,但我遇到了 AutoMapper 的问题,并将计算字段从我的域映射到我的视图模型。
这是我正在尝试做的一个例子:
界面
public interface IRequirement
{
int Id { get; set; }
... bunch of others
public decimal PlanOct { get; set; }
public decimal PlanNov { get; set; }
public decimal PlanDec { get; set; }
... and so on
decimal PlanQ1 { get; }
... etc
decimal PlanYear { get; }
... repeat for ActualOct, ActualNov ... ActualQ1 ... ActualYear...
}
领域模型
public class Requirement : IRequirement
{
public int Id { get; set; }
... bunch of others
public decimal PlanOct { get; set; }
public decimal PlanNov { get; set; }
public decimal PlanDec { get; set; }
... and so on
public decimal PlanQ1 { get { return PlanOct + PlanNov + PlanDec; } }
... etc
public decimal PlanYear { get { return PlanQ1 + PlanQ2 + PlanQ3 + PlanQ4; } }
... repeat for ActualOct, ActualNov ... ActualQ1 ... ActualYear...
}
还有 VarianceX 属性,即 VarianceOct 计算为 (PlanOct - ActualOct) 等。
我的视图模型看起来几乎完全相同,除了它具有默认的 getter/setter 语法而不是计算字段,例如:
public decimal PlanQ1 { get; set; }
我在 Global.asax 中的 AutoMapper 配置如下所示:
Mapper.CreateMap<Domain.Abstract.IRequirement, Models.Requirement.Details>();
这适用于除计算属性之外的所有属性。我的计算字段(即 *Q1、*Q2、*Q3、*Q4、*Year 和所有 Variance* 字段)都没有实际映射——它们都显示为默认值 0.00。
我对此感到很困惑,而且我也是这个和 AutoMapper 的新手,所以也许我错过了一些东西。我的直觉是,由于属性签名不相同(即域对象只有一个非默认的 getter 和没有 setter,而视图模型有默认的 getter 和 setter),所以 AutoMapper 没有选择它。但我也这样做了:
Mapper.CreateMap<Domain.Abstract.IRequirement, Models.Requirement.Details>()
.ForMember(dest => dest.PlanQ1, opt => opt.MapFrom(src => src.PlanQ1);
它仍然解析为 0。我也在调试器中确认了这一点。
我究竟做错了什么?
提前致谢。
编辑 1
在听从 Wal 的建议后,我运行了测试并且它成功了,所以我开始一步一步地向后工作,首先将 Field1/Field2/Field3 部分粘贴到接口/域/视图模型类中,并验证它在我的控制器中是否有效,然后一次改变一件事。我发现,由于我处理的是十进制类型,如果我在整数或双精度值中硬编码,那么我得到零,但如果我转换为十进制或使用十进制文字,那么它就可以工作。但前提是我手动设置它们,而不是从数据库中提取值。
换句话说,这有效(即 PlanQ1 = 6):
var D = new Requirement { PlanOct = (decimal) 1.0, PlanNov = (decimal) 2.0, PlanDec = (decimal) 3.0 };
var V = Mapper.Map<IRequirement, Details>(D);
这有效:
var D = new Requirement { PlanOct = 1M, PlanNov = 2M, PlanDec = 3M };
var V = Mapper.Map<IRequirement, Details>(D);
但这不会(从存储库对象中提取单个域对象,然后使用实体框架从 SQL Server 中提取):
var D = requirementRepository.Requirement(5);
var V = Mapper.Map<IRequirement, Details>(D);
综上所述,我得到的 PlanQ1 和 PlanYear 都是 0。我验证了域对象 (D) 中的 PlanOct = 1、PlanNov = 2 和 PlanDec = 3。我还验证了所有对象中的类型,包括EF生成的对象,都是十进制的,SQL Server的类型是十进制的。我什至尝试映射到创建的视图模型,只是为了排除这种情况,我仍然得到 PlanQ1 和 PlanYear 的 0:
var D = requirementRepository.Requirement(5);
var V = new Details();
Mapper.Map<IRequirement, Details>(D, V);