UseDestinationValue只有当目标属性不为null不为、属性、目标、UseDestinationValue

由网友(风扬起思念)分享简介:如何配置AutoMapper映射时,我想用行为从 UseDestinationValue 方法,但只有当目标属性不是空。这样的东西:Mapper.CreateMap<项目,ItemViewModel>().ForMember(X => x.Details,_ => _.UseDestinatio...

如何配置AutoMapper映射时,我想用行为从 UseDestinationValue 方法,但只有当目标属性不是

这样的东西:

  Mapper.CreateMap<项目,ItemViewModel>()
    .ForMember(X => x.Details,_ => _.UseDestinationValue(dontUseWhenNullDestination:真))
 

修改

 类ItemDetails {
    公共字符串信息{获得;组; }
    公共字符串ImportantData {获得;组; //只有在域,而不是在视图模型}
}

类项目{
    公共ItemDetails详细信息{获得;组; }
}

类ItemDetailsViewModel {
    公共字符串信息{获得;组; }
}

类ItemViewModel {
    公共ItemDetailsViewModel详细信息{获得;组; }
}
 

现在使用的例子。我有一个 ItemViewModel 类,我想把它映射到项目类。

映射配置:

  Mapper.CreateMap<项目,ItemViewModel>()
        .ForMember(X => x.Details,_ => _.UseDestinationValue())
 
天下手游 人物属性有哪些分类 人物属性详细介绍

第一种情况 - 目标属性 Item.Details 属性不为null。现在我想AutoMapper 使用的详细此目标实例属性,因为它不是空。

和逻辑是这样的:

  VAR项目=新项目{
    详情=新的细节{
        信息=老文,
        ImportantData =数据
    }
};

VAR itemViewModel =新ItemViewModel {
    详情=新DetailsViewModel {
        信息=新文本
    }
};

Mapper.Map(itemViewModel,项目);
 

AutoMapper,因为 UseDestinationValue 的presence,将离开 item.Details 实例,也是唯一的集 item.Details.Info 属性。

第二种情况 - 目标属性 Item.Details 属性为null。现在我想AutoMapper 不要使用这个空实例,而是创建新的。现在的问题是如何配置的映射考虑到这种情况?

的逻辑是这样的:

  VAR项目=新项目{
    详情= NULL
};

VAR itemViewModel =新ItemViewModel {
    详情=新DetailsViewModel {
        信息=新文本
    }
};

Mapper.Map(itemViewModel,项目);
 

问题

在这里,我有一个问题,因为映射之后, item.Details 属性将为null( UseDestinationValue 是在这种情况下)。

原因

NHibernate的,从数据库中获取实体后,把它变成一个代理。所以加载的对象的详细信息属性是一种不: ItemDetails ,而 ItemDetailsNHibernateProxy - 所以我必须使用这种类型的,当我想这个现有对象保存到数据库后。但是,如果这个属性是,那么我不能用一个空的目标数值,因此Automapper应该创建一个新的实例。

谢谢, 克里斯

解决方案

有同样的问题,但与EF。 Cryss的评论有关使用BeforeMap我指出了正确的方向。

我结束了code类似于:

在配置()方法:

  Mapper.CreateMap< ItemViewModel,项目>()
           .AfterMap((S,D)=> {MapDetailsAction(S,D);})
           .ForMember(DEST => dest.Details,选择=> opt.UseDestinationValue());
 

,则动作:

 动作< ItemViewModel,项目> MapDetailsAction =(源,目的地)=>
        {
            如果(destination.Details == NULL)
            {
                destination.Details =新的细节();
                destination.Details =
                    Mapper.Map< ItemViewModel,项目>(
                    source.Details,destination.Details);
            }
        };
 

How to configure AutoMapper mapping when I want to use behaviour from UseDestinationValue method, but only when destination property is NOT null.

Something like that:

Mapper.CreateMap<Item, ItemViewModel>()
    .ForMember(x => x.Details, _ => _.UseDestinationValue(dontUseWhenNullDestination: true))

EDIT

class ItemDetails {
    public string Info { get; set; }
    public string ImportantData { get; set; } // only in Domain, not in ViewModel
}

class Item {
    public ItemDetails Details { get; set; }
}

class ItemDetailsViewModel {
    public string Info { get; set; }
}

class ItemViewModel {
    public ItemDetailsViewModel Details { get; set; }
}

Now example of usage. I have a ItemViewModel class and I want to map it to the Item class.

Mapping configuration:

    Mapper.CreateMap<Item, ItemViewModel>()
        .ForMember(x => x.Details, _ => _.UseDestinationValue())

First case - destination property Item.Details property is NOT NULL. Now I want AutoMapper to use this destination instance of Details property, because it's not null.

And the logic looks like this:

var item = new Item { 
    Details = new Details {
        Info = "Old text",
        ImportantData = "Data"
    }
};

var itemViewModel = new ItemViewModel { 
    Details = new DetailsViewModel {
        Info = "New text"
    }
};       

Mapper.Map(itemViewModel, item);

AutoMapper, because of presence of UseDestinationValue, will leave the item.Details instance and set only item.Details.Info property.

Second case - destination property Item.Details property is NULL. Now I want AutoMapper not to use this null instance, but create new one. The question is how to configure the mapping to take into account this case?

The logic looks like this:

var item = new Item { 
    Details = null
};

var itemViewModel = new ItemViewModel { 
    Details = new DetailsViewModel {
        Info = "New text"
    }
};

Mapper.Map(itemViewModel, item);

PROBLEM

Here I have a problem, because after mapping, the item.Details property will be null (because of usage of UseDestinationValue which is null in this case).

REASON

NHibernate, after getting the entity from the database, puts it into a proxy. So the Details property of a loaded object is not of a type: ItemDetails, but ItemDetailsNHibernateProxy - so I have to use this type, when I want to save this existing object to the database later. But if this property is null, then I can't use a null destination value, so Automapper should create a new instance.

Thanks, Chris

解决方案

Had this same problem, but with EF. Cryss' comment about using BeforeMap pointed me in the right direction.

I ended up with code similar to:

In the Configure() method:

Mapper.CreateMap<ItemViewModel, Item>()
           .AfterMap((s, d) => { MapDetailsAction(s, d); })
           .ForMember(dest => dest.Details, opt => opt.UseDestinationValue());

Then the Action:

Action<ItemViewModel, Item> MapDetailsAction = (source, destination) =>
        {
            if (destination.Details == null)
            {
                destination.Details = new Details();
                destination.Details =
                    Mapper.Map<ItemViewModel, Item>(
                    source.Details, destination.Details);
            }
        };