Automapper返回一个空集合,我想要一个null

时间:2016-02-09 13:29:23

标签: c# .net automapper

public class Person
{
   Name { get; set; }
   IEnumerable<Address> Addresses { get; set; }
}

public class PersonModel
{
   Name { get; set; }
   IEnumerable<AddressModel> Addresses { get; set; }
}

如果我将Person映射到PersonModel,请执行以下操作:

Mapper.DynamicMap<Person, PersonModel>(person);

如果Addresses上的Person属性为空,则它们将PersonModel映射为空Enumerable而不是空。

如何让PersonModelAddresses而不是空Enumerable

6 个答案:

答案 0 :(得分:26)

简单的答案是使用AllowNullCollections

AutoMapper.Mapper.Initialize(cfg =>
{
    cfg.AllowNullCollections = true;
});

或者如果您使用实例API

new MapperConfiguration(cfg =>
{
    cfg.AllowNullCollections = true;
}

答案 1 :(得分:8)

因此,使用Automapper可能有几种方法可以实现这一点,而这只是一个:

Mapper.CreateMap<Person, PersonMap>()
   .AfterMap( (src, dest) => dest.Addresses = dest.Addresses?.Any() ? dest.Addresses : null );

此代码使用新的c#?.运算符来确保空的安全性,因此如果您无法在代码中使用该功能,则可能需要将其删除并检查为空。

答案 2 :(得分:2)

另一种替代方法是使用条件,因此仅在值不为null时映射该值。 这可能要求值默认为null(因为它不会被映射)

{{1}}

答案 3 :(得分:1)

您应该能够为要使用此行为的属性定义自定义解析程序。如下所示:

Mapper.CreateMap<Address, AddressModel>();
Mapper.CreateMap<Person, PersonModel>()
    .ForMember(
        dest => dest.Addresses,
        opt => opt.ResolveUsing(person => person.Addresses.Any() ? person.Addresses.Select(Mapper.Map<Address, AddressModel>) : null));

答案 4 :(得分:1)

如果您希望将其作为 API 中的一般规则,您可以像这样在配置服务方法中配置 Automapper。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddControllers();
            [...]
            // configure automapping
            services.AddAutoMapper(cfg => cfg.AllowNullCollections = true, typeof(Startup));               
        }

或者,如果在单独的 DLL 中使用 Automapping(例如:对于 DTO 服务),我更喜欢使用辅助函数,因此也应该在那里进行配置:

    public static class MappingHelper
    {
        private static readonly Lazy<IMapper> _lazy = new(() =>
        {
            var config = new MapperConfiguration(cfg =>
            {
                // This line ensures that internal properties are also mapped over.
                cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
                cfg.AddProfile<DomainToRepositoryProfile>();
                cfg.AddProfile<RepositoryToDomainProfile>();
                cfg.AllowNullCollections = true;
            });
            var mapper = config.CreateMapper();
            return mapper;
        });

        public static IMapper Mapper => _lazy.Value;
    }

答案 5 :(得分:0)

除了在the mapper configuration initialization中设置ACTION_CANCEL(如this answer中所述)之外,您还可以选择在AllowNullCollections定义中设置AllowNullCollections,例如这个:

Profile