AutoMapper不映射计算领域的标 [英] AutoMapper doesn't map calculated field to scalar

查看:186
本文介绍了AutoMapper不映射计算领域的标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我的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< D​​omain.Abstract.IRequirement,Models.Requirement.Details>();

这工作正常上的除了那些计算出所有属性的。我计算领域的无(即* Q1,Q2 *,* Q3,Q4 *,*年,和所有的差异*字段)实际上映射 - 他们都表现出了0.00的默认值

我难倒这个pretty,我也是在这个和AutoMapper一个新手,所以也许我错过了什么。我的直觉是,由于物业的签名不相同(即域对象只有一个非默认的getter和没有setter,而视图模型具有默认的getter和setter),那么AutoMapper不捡不起来。但我也这样做:

  Mapper.CreateMap< D​​omain.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆