AutoMapper如何全局配置map条件过滤null值空值对所有映射起效

我们在使用Automapper的时候经常会遇到这样的问题:假设展示给用户的数据我们用UserDto类,User类就是我们的实体类。在给用户编辑的时候,我们可能某些字段在数据库中为Null,这时候需要一些默认值 比如这里UserDto中的BirTime,然后我们有一些人的习惯是在构造函数里面进行赋值

  public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public  DateTime? BirTime{ get; set; }
    }

   public class UserDto
    {
         public UserDto()
        {
             this.BirTime=DateTime.Now;//把当前时间赋值给BirTime
        }
        public string Name { get; set; }
        public  DateTime? BirTime{ get; set; }
    }

 //假设我们从数据库中取出来的值是这样的,然后我们要和UserDto之间进行转换
   User user = new User()
    {
        Id = 1,
        Name = "caoyc",
        BirTime=null
    };
  UserDto userDto=user.MapTo<UserDto>();//这里把实体类转换成前台给用户展示的UserDto类

看似这里的代码都没有什么问题,但是我想在BirTimenull值的时候使用我UserDto类中的默认值 也就是当前时间,但在实际操作之后就会发现转换过后的UserDto的值已经变掉了。那么问题来了, 如何才能使用默认值呢。

方法有很多,比如

//第一种方法
UserDto userDto=user.MapTo<UserDto>();//这里把实体类转换成前台给用户展示的UserDto类
userDto.BirTime=userDto.BirTime==null?DateTime.Now:userDto.BirTime;

第一种方法就是在自己转换完成之后判断一下,然后重新赋值,用这种方法的话那写构造函数自然就没什么必要了

//第二种方法
Mapper.CreateMap<User, UserDto>().ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));

第二种方法不怎么好,当你需要转换的类很多的时候,每个都要这样写,会很多也会很烦

//第三种方法,在全局配置的时候加上这句话
private static void CreateMappingsInternal(IMapperConfigurationExpression cfg)
{
     //没错就是这句话
     cfg.ForAllMaps((a, b) => b.ForAllMembers(opt => opt.Condition((src, dest, sourceMember) => sourceMember != null)));
}

个人比较推荐第三种方法,不过这就相当于一棒子打死了,有利也有弊。

.NET Web API的Global.asax.cs

using Application.Dtos;
using Autofac;
using Autofac.Integration.WebApi;
using AutoMapper;
using AutoMapper.Configuration;
using Repositories.Cliente;
using System;
using System.Linq;
using System.Reflection;
using System.Web.Http;

namespace WebApi
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);

            var builder = new ContainerBuilder();

            var config = GlobalConfiguration.Configuration;

            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            builder
                .RegisterAssemblyTypes(typeof(ClienteRepository).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces().InstancePerRequest();

            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            var mapper = new MapperConfigurationExpression();

            CreateMappingsInternal(mapper);

            Mapper.Initialize(mapper);
        }

        //全局配置
        private static void CreateMappingsInternal(IMapperConfigurationExpression mapper)
        {

        }
    }
}

.NET Core的Startup.cs的ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddControllers()
                .AddNewtonsoftJson();

            services.AddMvc();
             
            //...............
 
            services.AddAutoMapper(typeof(AccountProfile));

            var configuration = new MapperConfiguration(cfg =>
            {
                cfg.ForAllMaps((obj, cnfg) =>
                    cnfg.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null)));
            }); 
        }

AutoMapper条件映射实战

//有条件的对象拷贝
AutoMapper.Mapper.Initialize(cfg =>
                        {
                            cfg.CreateMap<OrderInfo, OrderInfo>()
                                .ForAllMembers(opts => opts.Condition((src, dest, srcMember, dMember) =>
                                srcMember != null && srcMember.ToString() != ""));
                        });

AutoMapper.Mapper.Map<OrderInfo, OrderInfo>(mainOrder, myorderinfo);


AutoMapper.Map忽略来自源对象中的所有空值的属性

using AutoMapper;
using NUnit.Framework;

namespace Tests.UI
{
    [TestFixture]
    class AutomapperTests
    {

      public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int? Foo { get; set; }
        }

        [Test]
        public void TestNullIgnore()
        {
            Mapper.CreateMap<Person, Person>()
                    .ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));

            var sourcePerson = new Person
            {
                FirstName = "Bill",
                LastName = "Gates",
                Foo = null
            };
            var destinationPerson = new Person
            {
                FirstName = "",
                LastName = "",
                Foo = 1
            };
            Mapper.Map(sourcePerson, destinationPerson);

            Assert.That(destinationPerson,Is.Not.Null);
            Assert.That(destinationPerson.Foo,Is.EqualTo(1));
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值