AutoMapper不映射计算领域的标 [英] AutoMapper doesn't map calculated field to scalar
问题描述
我想我的MVC3项目分为一个适当的DAL /域/视图模型架构,但我正在与AutoMapper和我的域名我的看法模型映射计算领域的一个问题。
这里是什么我试图做一个例子:
接口
公共接口IRequirement
{
INT标识{搞定;组; }
...一堆别人的
公共小数PlanOct {搞定;组; }
公共小数PlanNov {搞定;组; }
公共小数PlanDec {搞定;组; }
... 等等
小数PlanQ1 {搞定; }
...等
小数PlanYear {搞定; }
......重复ActualOct,ActualNov ... ... ActualQ1 ... ActualYear
}
域模型
公共类要求:IRequirement
{
公众诠释标识{搞定;组; }
...一堆别人的
公共小数PlanOct {搞定;组; }
公共小数PlanNov {搞定;组; }
公共小数PlanDec {搞定;组; }
... 等等
公共小数PlanQ1 {{返回PlanOct + PlanNov + PlanDec; }}
...等
公共小数PlanYear {{返回PlanQ1 + PlanQ2 + PlanQ3 + PlanQ4; }}
......重复ActualOct,ActualNov ... ... ActualQ1 ... ActualYear
}
有也VarianceX的性质,即VarianceOct其计算公式为(PlanOct - ActualOct)等
我的观点模型看起来几乎一模一样,除了没有计算领域具有默认的getter / setter语法,例如:
公共小数PlanQ1 {搞定;组; }
在Global.asax中我AutoMapper的配置是这样的:
Mapper.CreateMap< Domain.Abstract.IRequirement,Models.Requirement.Details>();
这工作正常上的除了那些计算出所有属性的。我计算领域的无(即* Q1,Q2 *,* Q3,Q4 *,*年,和所有的差异*字段)实际上映射 - 他们都表现出了0.00的默认值
我难倒这个pretty,我也是在这个和AutoMapper一个新手,所以也许我错过了什么。我的直觉是,由于物业的签名不相同(即域对象只有一个非默认的getter和没有setter,而视图模型具有默认的getter和setter),那么AutoMapper不捡不起来。但我也这样做:
Mapper.CreateMap< Domain.Abstract.IRequirement,Models.Requirement.Details>()
.ForMember(DEST => dest.PlanQ1,选择=> opt.MapFrom(SRC => src.PlanQ1);
和它仍然决心为0。我在调试器证实了这一点。
我在做什么错了?
先谢谢了。
修改1
以下沃尔玛的意见后,我跑的测试和它的工作,所以我开始工作的字段1 /字段2 /字段3件入接口/域/视图模型类倒退一步一个时间,第一粘贴并验证它的工作我的控制器,再一次改变一件事。我发现的是,因为我处理小数类型,如果我在整数或双精度值硬code然后我得到零,但如果我投来一个小数或使用十进制字面那么它的作品。但是,只有当我手动设置,如果不拉我从数据库中值。
在换句话说,这个工作(即PlanQ1 = 6):
变种D =新的要求{PlanOct =(十进制)1.0,PlanNov =(十进制)2.0,PlanDec =(十进制)3.0};
变种V = Mapper.Map< IRequirement,详情及GT;(D);
和这个作品:
变种D =新的要求{PlanOct = 1M,PlanNov = 2M,PlanDec = 3M};
变种V = Mapper.Map< IRequirement,详情及GT;(D);
但是,这并不(从一个资源库对象拉一个单一的域对象,这反过来使用实体框架从SQL Server拉):
变种D = requirementRepository.Requirement(5);
变种V = Mapper.Map< IRequirement,详情及GT;(D);
通过上面我得到的是0 PlanQ1和PlanYear。我已验证PlanOct = 1,PlanNov = 2,和PlanDec = 3在域对象(D)。我还证实,在所有对象,包括EF生成的对象类型,十进制和SQL服务器类型是小数。我甚至尝试映射到创建的视图模式,只是为了排除这种可能性,我仍然得到0 PlanQ1和PlanYear:
变种D = requirementRepository.Requirement(5);
变种V =新的细节();
Mapper.Map< IRequirement,详情及GT;(D,V);
刚刚意识到这是没有答案,所以我想关闭它。从技术上讲,因为我无法得到Automapper在这种情况下由于某种原因发挥好它是无人接听。我清盘做的是回去和创建几个映射方法,我的仓库里,一到DAL对象的单个实例映射到IRequirement对象,一个映射的集合。然后在存储库,而不是调用Mapper.Map我只是叫我的自定义映射的方法和它完美的作品。
我还是不明白,为什么这并不工作,但我已经遇到一些其他类的地方Automapper只是抛出了,我必须手动映射至少有一个或两个领域,虽然Automapper确实照顾其余的在这些情况。
我敢肯定有一些事情,我只是不明白呢。但在任何情况下,回落至部分或完全手动映射是我的解决方法。
I am trying to separate my MVC3 project into a proper DAL/Domain/ViewModel architecture, but I'm running into a problem with AutoMapper and mapping calculated fields from my domain to my view model.
Here's an example of what I'm trying to do:
Interface
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...
}
Domain Model
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...
}
There are also VarianceX properties, i.e. VarianceOct which is calculated as (PlanOct - ActualOct), etc.
My view model looks almost exactly the same, except instead of calculated fields it has the default getter/setter syntax, for example:
public decimal PlanQ1 { get; set; }
My AutoMapper config in Global.asax looks like this:
Mapper.CreateMap<Domain.Abstract.IRequirement, Models.Requirement.Details>();
This works fine on all properties except the calculated ones. None of my calculated fields (i.e. *Q1, *Q2, *Q3, *Q4, *Year, and all the Variance* fields) are actually mapped -- they all show up with the default value of 0.00.
I'm pretty stumped on this, and I'm also a novice at this and AutoMapper, so maybe I missed something. My intuition is that since the property signatures aren't identical (i.e. the domain object has only a non-default getter and no setter, while the view model has default getter and setter) then AutoMapper isn't picking it up. But I also did this:
Mapper.CreateMap<Domain.Abstract.IRequirement, Models.Requirement.Details>()
.ForMember(dest => dest.PlanQ1, opt => opt.MapFrom(src => src.PlanQ1);
And it still resolved to 0. I confirmed this in the debugger as well.
What am I doing wrong?
Thanks in advance.
EDIT 1
After following Wal's advice I ran the test and it worked, so I began working backwards one step at a time, first pasting in the Field1/Field2/Field3 parts into the interface/domain/view model classes and verifying it worked in my controller, then changing one thing at a time. What I found is that, since I am dealing with decimal types, if I hard-code in integer or double values then I get zero, but if I cast to a decimal or use a decimal literal then it works. But only if I manually set them, not if I pull the values from the database.
In other words, this works (i.e. 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);
And this works:
var D = new Requirement { PlanOct = 1M, PlanNov = 2M, PlanDec = 3M };
var V = Mapper.Map<IRequirement, Details>(D);
But this does not (pulling a single domain object from a repository object, that in turn pulls from SQL Server using Entity Framework):
var D = requirementRepository.Requirement(5);
var V = Mapper.Map<IRequirement, Details>(D);
With the above all I get is 0 for PlanQ1 and PlanYear. I verified that PlanOct = 1, PlanNov = 2, and PlanDec = 3 in the domain object (D). I also verified that the type in all objects, including the EF generated object, is decimal, and the SQL Server type is decimal. I even tried mapping to a created view model, just to rule that out, and I still get 0 for PlanQ1 and PlanYear:
var D = requirementRepository.Requirement(5);
var V = new Details();
Mapper.Map<IRequirement, Details>(D, V);
Just realized this was left unanswered so I wanted to close it out. Technically it is unanswered because I couldn't get Automapper to play nice in this scenario for some reason. What I wound up doing is going back and creating a couple of mapping methods inside my repository, one to map a single instance of the DAL object to the IRequirement object, and one to map a collection. Then in the repository instead of calling Mapper.Map I just call my custom mapping methods and it works perfectly.
I still don't understand why this doesn't work, but I've run into a few other classes where Automapper just throws up and I have to manually map at least one or two fields, though Automapper does take care of the rest in those cases.
I'm sure there's something about it I just don't see yet. But in any case, falling back to partial or fully manual mapping was my workaround.
这篇关于AutoMapper不映射计算领域的标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!