如何根据类型忽略属性

How to ignore properties based on their type

我正在使用 AutoMapper 将 entity framework 对象复制到另一个相同的数据库。问题是它试图复制查找表。

我试图用 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");
});

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

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:这也很漂亮 "hackish",因为它试图将所有类型的属性映射到那里(readonly/non-public,等等)所以对它持保留态度。

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

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";
}

关于如何将配置应用于 Mappermapper.CreateMapper 调用创建的内容似乎很愚蠢。我正在调查它,看看我是否能找到更多信息,如果我找到任何东西,我会更新这个答案。