基于目标值的C# AutoMapper条件映射

13
请问有人可以指导如何在AutoMapper中使用条件映射,根据现有的目标属性值从源对象映射到目标对象中的一个值?我的源类是:
public class UserDetails
{
    public String Nickname { get; set; }
}

我的目标类是:

public class ProfileViewModel
{
    public Boolean NicknameIsVisible { get; set;
    public String Nickname { get; set; }
}

我希望将目标对象中的“Nickname”属性值设置为与源对象中的“Nickname”属性值匹配,但前提是目标对象的“NicknameIsVisible”属性值已经设置为TRUE。否则,我希望将目标对象的“Nickname”属性值设置为空字符串。
我尝试过类似于以下代码(无法编译)...
Mapper.CreateMap<UserDetails, ProfileViewModel>()
.ForMember(
            destination => destination.Nickname,
            option => option.
                .MapFrom(
                    source => source.NicknameIsVisible ? 
                    source.Nickname :
                    String.Empty)
);

但是“NicknameIsVisible”不是我的源代码的属性,而是我的目标代码的属性。
顺便说一下,我的ProfileViewModel使用Owain Wragg的方法绑定到三个实体(http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx),另一个实体提供了“NicknameIsVisible”属性的值。
请问有人能建议我如何解决这个问题的正确语法吗?
2个回答

15

试一下这个:

Mapper.CreateMap<UserDetails, ProfileViewModel>()
.ForMember(
        destination => destination.Nickname,
        option => 
        {
            option.Condition(rc => 
            {
                var profileViewModel = (ProfileViewModel)rc.InstanceCache.First().Value;
                return profileViewModel.NicknameIsVisible;
            });

            option.MapFrom(source => source.Nickname);
        }
);

谢谢。我稍后会尝试并告诉你。 - Dib
我在使用你的示例时遇到了编译错误。我已经将代码更改为以下版本以使其编译: - Dib
这是哪个版本?在我的版本中,rc是源对象,仅包含源属性。像InstanceCache这样的东西不存在。 - JSON

6

参照devduder的示例,我现在有了以下可编译的代码:

.ForMember(
    destination => destination.Nickname,
    option => 
    {
        option.Condition(resolutionContext =>
            (resolutionContext.InstanceCache.First().Value as ProfileViewModel).NicknameIsVisible);
        option.MapFrom(source => source.Nickname);
    }
);

然而,虽然代码可以编译并运行,但是它没有将目标昵称(Nickname)填充到任何内容中。编辑:我不得不改变我的映射顺序,所以首先映射了偏好对象(该对象具有“昵称可见性”属性的值),因此该值可用于测试!所以我的三方映射调用是:
var profileViewModel = EntityMapper.Map<ProfileViewModel>(preferences, member, account);

这样可以确保preferences对象首先映射到ViewModel,然后在值被设置后,account对象的条件映射就可以进行了。 所以这是我的解决方案,但我不能投票支持自己的答案!

我认为可能是因为目标中的属性尚未设置,因此无法使用它。我可能需要更改我的映射顺序以实现所需的功能。我会及时反馈我的发现。 - Dib
1
请告诉我们你的进展,我很想知道你发现了什么。 - devduder
我改变了映射发生的顺序,所以在我的代码中上面的条件被测试之前就已经满足了。因此,本质上对我有效的代码就是这里的代码。但是非常感谢@devduder,他建议的代码让我一开始就找到了解决方案的正确方向。 - Dib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接