C#汽车制造商->;条件映射

C#汽车制造商->;条件映射,c#,conditional,automapper,C#,Conditional,Automapper,我正在尝试做一些条件映射,我读过的所有文档和问题似乎都没有涵盖这个特定的条件映射。我希望这里的人能有经验或知道如何用最好的方法来解决这个问题 我正在映射一个具有两个属性的对象。但是,如果特定属性具有值,我不想映射这两个属性。要将此可视化: foreach(var object in objectB) { If (object.propertyA == "SomeValue") continue; else Mapper.Map<ObjectA

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

我正在映射一个具有两个属性的对象。但是,如果特定属性具有值,我不想映射这两个属性。要将此可视化:

foreach(var object in objectB) {
    If (object.propertyA == "SomeValue")
        continue;
    else
        Mapper.Map<ObjectA>(object);
}
但上述版本显然不起作用。
提前感谢您的帮助。

可以使用条件映射实现,有关详细信息,请参阅文档()。为了涵盖数组过滤的情况,我创建了一个自定义类型转换器,这有点棘手(请参阅)。下面是更新后的示例

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; }
    }
}
使用AutoMapper;
使用制度;
使用System.Collections.Generic;
名称空间ConsoleAppTest2
{
班级计划
{
静态void Main(字符串[]参数)
{
Mapper.Initialize(cfg=>{
//对特定阵列使用特定类型转换器
cfg.CreateMap().ConvertUsing(新的ArrayFilterTypeConverter(
(src,dest)=>(src.Age>0)
));
cfg.CreateMap()
.ForMember(dest=>dest.Age,opt=>opt.Condition(src=>(src.Age>=0)))
.FormMember(dest=>dest.CurrentAddress,opt=>
{
选择条件(src=>(src.Age>=0));
opt.MapFrom(src=>src.Address);
});
});
var foo=new foo(){Name=“Name”,Address=“Address”,Age=-1};
var fooDTO=新fooDTO();
var fooArray=new Foo[]{
new Foo(){Name=“Name1”,Address=“Address1”,Age=-1},
new Foo(){Name=“Name2”,Address=“Address2”,Age=1},
新建Foo(){Name=“Name3”,Address=“Address3”,Age=1}
};
var fooDTOArray=Mapper.Map(fooArray);//获取2个元素而不是3个元素
Mapper.Map(foo,fooDTO);
//由于年龄为负,因此我们跳过了地址和年龄属性
Console.ReadLine();
}
}
公共类ArrayFilterTypeConverter:ITypeConverter
{
私有Func滤波器;
公共阵列过滤器类型转换器(Func过滤器)
{
this.filter=过滤器;
}
公共TDestArray转换(TSourceArray源、TDestArray目标、ResolutionContext上下文)
{
var sourceArray=源为TSource[];
List destList=新列表();
var typeMap=context.ConfigurationProvider.ResolveTypeMap(typeof(TSource),typeof(TDest));
foreach(sourceArray中的var src)
{
var dest=context.Mapper.Map(src);
if(过滤器(src、dest))
目的地列表。添加(目的地);
}
//向TDestArray施放阵列的小技巧
var result=(TDestArray)(object)destList.ToArray();
返回结果;
}
}
内部类FooDto
{
公共字符串名称{get;set;}
公共字符串CurrentAddress{get;set;}
公共整数{get;set;}
}
内部类Foo
{
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公共整数{get;set;}
}
}

可以使用条件映射实现,有关详细信息,请参阅文档()。为了涵盖数组过滤的情况,我创建了一个自定义类型转换器,这有点棘手(请参阅)。下面是更新后的示例

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; }
    }
}
使用AutoMapper;
使用制度;
使用System.Collections.Generic;
名称空间ConsoleAppTest2
{
班级计划
{
静态void Main(字符串[]参数)
{
Mapper.Initialize(cfg=>{
//对特定阵列使用特定类型转换器
cfg.CreateMap().ConvertUsing(新的ArrayFilterTypeConverter(
(src,dest)=>(src.Age>0)
));
cfg.CreateMap()
.ForMember(dest=>dest.Age,opt=>opt.Condition(src=>(src.Age>=0)))
.FormMember(dest=>dest.CurrentAddress,opt=>
{
选择条件(src=>(src.Age>=0));
opt.MapFrom(src=>src.Address);
});
});
var foo=new foo(){Name=“Name”,Address=“Address”,Age=-1};
var fooDTO=新fooDTO();
var fooArray=new Foo[]{
new Foo(){Name=“Name1”,Address=“Address1”,Age=-1},
new Foo(){Name=“Name2”,Address=“Address2”,Age=1},
新建Foo(){Name=“Name3”,Address=“Address3”,Age=1}
};
var fooDTOArray=Mapper.Map(fooArray);//获取2个元素而不是3个元素
Mapper.Map(foo,fooDTO);
//由于年龄为负,因此我们跳过了地址和年龄属性
Console.ReadLine();
}
}
公共类ArrayFilterTypeConverter:ITypeConverter
{
私有Func滤波器;
公共阵列FilterTypeConverter(函数f