UseDestinationValue只有当目标属性不为null [英] UseDestinationValue only when destination property is not null

查看:184
本文介绍了UseDestinationValue只有当目标属性不为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何配置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())
 

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

    和逻辑是这样的:

      VAR项目=新项目{
        详情=新的细节{
            信息=老文,
            ImportantData =数据
        }
    };
    
    VAR itemViewModel =新ItemViewModel {
        详情=新DetailsViewModel {
            信息=新文本
        }
    };
    
    Mapper.Map(itemViewModel,项目);
     

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

  2. 第二种情况 - 目标属性 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())

  1. 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.

  2. 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);
            }
        };

这篇关于UseDestinationValue只有当目标属性不为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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