如何根据类型忽略属性

时间:2016-03-16 16:54:48

标签: c# automapper

我使用AutoMapper将实体框架对象复制到另一个相同的数据库。问题是它试图复制查找表。

我尝试使用AddGlobalIgnoreShouldMapProperty排除它们,但它不起作用。 AutoMapper仍尝试复制这些属性。

这是我的代码。我想忽略以" LU"

开头的属性
 dynamic newObject= new NewObject();

 MapperConfiguration config = new MapperConfiguration(cfg =>
 {
     cfg.CreateMissingTypeMaps = true;
     cfg.AddGlobalIgnore("LU");
     cfg.ShouldMapProperty = p => !p.GetType().ToString().StartsWith("LU");
     cfg.ShouldMapField = p => !p.GetType().ToString().StartsWith("LU");
 });
 IMapper mapper = config.CreateMapper();
 newObject = mapper.Map(objectToCopy, objectToCopy.GetType(), newObject.GetType()); 

我也尝试了

MapperConfiguration config = new MapperConfiguration(cfg =>
{
   cfg.CreateMissingTypeMaps = true;
   cfg.AddGlobalIgnore("LU");
   cfg.ShouldMapProperty = p => !p.PropertyType.Name.StartsWith("LU");
   cfg.ShouldMapField = p => !p.FieldType.Name.StartsWith("LU");
 });

MapperConfiguration config = new MapperConfiguration(cfg =>
{
   cfg.CreateMissingTypeMaps = true;
   cfg.AddGlobalIgnore("LU");
   cfg.ShouldMapProperty = p => !p.Name.StartsWith("LU");
   cfg.ShouldMapField = p => !p.Name.StartsWith("LU");
});

2 个答案:

答案 0 :(得分:4)

将配置创建为单独的配置文件,然后将该配置文件添加到映射器配置中。

class Program
{
    static void Main(string[] args)
    {
        dynamic newObject = new NewObject();
        var objectToCopy = new ObjectToCopy();

        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<MyProfile>();
        });

        var mapper = config.CreateMapper();
        mapper.Map(objectToCopy, newObject);
        // newObject.LU_Ignore = "Original value"
        // newObject.DoNotIgnore = "New value"
    }
}

class MyProfile : Profile
{
    protected override void Configure()
    {
        CreateMissingTypeMaps = true;
        ShouldMapProperty = p => !p.Name.StartsWith("LU"); // this is the correct way to get the property name
    }
}

class ObjectToCopy
{
    public string LU_Ignore { get; set; } = "New value";

    public string DoNotIgnore { get; set; } = "New value";
}


class NewObject
{
    public string LU_Ignore { get; set; } = "Original value";

    public string DoNotIgnore { get; set; } = "Original value";
}

关于如何将配置应用于Mapper调用创建的mapper.CreateMapper,似乎有些愚蠢。我正在研究它是否可以找到更多信息,如果我发现任何内容,我会更新这个答案。

答案 1 :(得分:0)

我不会说这是最好的(高效或设计方面)方法,但这样做有效:

public static class AutoExtensions {
    public static IMappingExpression Ignore(this IMappingExpression expression, Func<PropertyInfo, bool> filter) {
        foreach (var propertyName in expression
            .TypeMap
            .SourceType
            .GetProperties()
            .Where(filter)
            .Select(x=>x.Name))
        {
            expression.ForMember(propertyName, behaviour => behaviour.Ignore());
        }

        return expression;
    }
}

您可以像这样配置映射器(对于这些示例类):

public class Client {
    public string LUName { get; set; }
    public string Dno { get; set; } 
}

public class ClientDTO
{
    public string LUName { get; set; }
    public string Dno { get; set; } 
}

并像这样测试:

private static void ConfigAndTestMapper() {
        var config = new MapperConfiguration(cfg =>{
            cfg.CreateMap(typeof (Client), typeof (ClientDTO))
                .Ignore(x => x.Name.StartsWith("LU"));
        });

        var mapper = config.CreateMapper();
        var result = mapper.Map<ClientDTO>(new Client() {LUName = "Name", Dno = "Dno"});

        var isIgnored = result.LUName == null;
    }
PS:这也很漂亮&#34; hackish&#34;因为它试图在那里映射所有类型的属性(只读/非公开等),所以要带上一粒盐。