c# - 仅当目标属性不为 null 时才使用 DestinationValue

标签 c# .net automapper

当我想使用 UseDestinationValue 方法的行为时如何配置 AutoMapper 映射,但仅当目标属性不是 null 时。

类似的东西:

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

编辑

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; }
}

现在是用法示例。我有一个 ItemViewModel 类,我想将它映射到 Item 类。

映射配置:

    Mapper.CreateMap<Item, ItemViewModel>()
        .ForMember(x => x.Details, _ => _.UseDestinationValue())
  1. 第一种情况 - 目标属性 Item.Details 属性不是 NULL。现在我希望 AutoMapper 使用 Details 属性的目标实例,因为它不为空。

    逻辑是这样的:

    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,由于 UseDestinationValue 的存在,将保留 item.Details 实例并仅设置 item.Details.Info 属性。

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

    逻辑是这样的:

    var item = new Item { 
        Details = null
    };
    
    var itemViewModel = new ItemViewModel { 
        Details = new DetailsViewModel {
            Info = "New text"
        }
    };
    
    Mapper.Map(itemViewModel, item);
    

    问题

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

原因

NHibernate 从数据库中获取实体后,将其放入代理中。所以加载对象的 Details 属性不是类型:ItemDetails,而是 ItemDetailsNHibernateProxy - 所以我必须使用这种类型,当我想要稍后将此现有对象保存到数据库中。但如果此属性为 null,则我不能使用 null 目标值,因此 Automapper 应该创建一个新实例。

谢谢, 克里斯

最佳答案

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

我最终得到的代码类似于:

在 Configure() 方法中:

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

然后是 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);
            }
        };

关于c# - 仅当目标属性不为 null 时才使用 DestinationValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12262940/

相关文章:

.net - Excel xml 电子表格 - 是否可以嵌入图像?

.net - 在 WPF 应用程序中 native 拦截按键操作的方法

automapper - AutoMapper:如果source == null,则创建目标类型的实例

c# - 将对象复制到对象(使用 Automapper?)

c# - Visual Studio 2010 : Binding Issues

c# - 仅某些页面需要 JavaScript 和 jQuery

c# - 使用 WIF 在 Asp.Net 4.5 上自定义身份验证

c# - 一个类 ViewModel 中的 AutoMapper 多个类,每个类都有属性

c# - 应用程序范围的观察者是有效的解决方案吗?

c# - 如何从静态资源为 UWP 中的依赖属性添加默认值