首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C#自动映射器->条件映射

C#自动映射器->条件映射
EN

Stack Overflow用户
提问于 2018-07-31 22:54:54
回答 1查看 4.5K关注 0票数 1

我正在尝试做一些条件映射,我读过的所有文档和问题似乎都没有涵盖这个特定的条件。我希望这里的人能有经验,或者知道如何才是最好的方法。

我正在映射一个具有两个属性的对象。但是,如果某个特定属性具有值,则我不想映射这两个属性。要将其可视化,请执行以下操作:

foreach(var object in objectB) {
    If (object.propertyA == "SomeValue")
        continue;
    else
        Mapper.Map<ObjectA>(object);
}

但是,我想要上述语句的AutoMapper等效项。所以更像是这样:

cfg.CreateMap<ObjectB, ObjectA>()
    .ForMember(dest => dest.PropertyA, m => m.Condition(source => source.PropertyA != "SomeValue"))
    .ForMember(dest => dest.PropertyB, m => m.Condition(source => source.PropertyA != "SomeVAlue" ? source.PropertyB : ignore))

但是上面的版本显然不起作用。提前感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-31 23:50:09

可以使用条件映射来实现,有关详细信息,请参阅文档(http://docs.automapper.org/en/latest/Conditional-mapping.html)。为了涵盖数组过滤的情况,我创建了一个自定义类型转换器,这有点棘手(参见http://docs.automapper.org/en/stable/Custom-type-converters.html)。更新后的示例如下

using AutoMapper;
using System;
using System.Collections.Generic;

namespace ConsoleAppTest2
{
    class Program
    {
        static void Main(string[] args)
        {

            Mapper.Initialize(cfg => {
                //Using specific type converter for specific arrays
                cfg.CreateMap<Foo[], FooDto[]>().ConvertUsing(new ArrayFilterTypeConverter<Foo[], FooDto[], Foo, FooDto>(
                                                                                                               (src, dest) => (src.Age > 0)
                                                                                                            ));

                cfg.CreateMap<Foo, FooDto>()
                    .ForMember(dest => dest.Age, opt => opt.Condition(src => (src.Age >= 0)))
                    .ForMember(dest => dest.CurrentAddress, opt =>
                                                                {
                                                                    opt.Condition(src => (src.Age >= 0));
                                                                    opt.MapFrom(src => src.Address);
                                                                });

            });

            var foo = new Foo() { Name = "Name", Address = "Address", Age = -1 };
            var fooDTO = new FooDto();


            var fooArray = new Foo[] {
                    new Foo() { Name = "Name1", Address = "Address1", Age = -1 },
                    new Foo() { Name = "Name2", Address = "Address2", Age = 1 },
                    new Foo() { Name = "Name3", Address = "Address3", Age = 1 }
            };

            var fooDTOArray =  Mapper.Map<Foo[], FooDto[]>(fooArray); //get 2 elements instead of 3

            Mapper.Map(foo, fooDTO);
            //The result is we skipped Address and Age properties becase Age is negative

            Console.ReadLine();
        }
    }

    public class ArrayFilterTypeConverter<TSourceArray, TDestArray, TSource, TDest> : ITypeConverter<TSourceArray, TDestArray>
    {
        private Func<TSource, TDest, bool> filter;

        public ArrayFilterTypeConverter(Func<TSource, TDest, bool> filter)
        {
            this.filter = filter;
        }

        public TDestArray Convert(TSourceArray source, TDestArray destination, ResolutionContext context)
        {
            var sourceArray = source as TSource[];
            List<TDest> destList = new List<TDest>();

            var typeMap = context.ConfigurationProvider.ResolveTypeMap(typeof(TSource), typeof(TDest));

            foreach (var src in sourceArray)
            {
                var dest = context.Mapper.Map<TSource, TDest>(src);

                if (filter(src, dest))
                    destList.Add(dest);
            }

            // Little hack to cast array to TDestArray
            var result = (TDestArray)(object)destList.ToArray();
            return result;
        }
    }

    internal class FooDto
    {
        public string Name { get; set; }
        public string CurrentAddress { get; set; }
        public int Age { get; set; }

    }

    internal class Foo
    {
        public string Name { get; set; }
        public string Address { get; set; }

        public int Age { get; set; }
    }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51616335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档