C# 在相同的两种对象类型之间创建两个 Automapper 贴图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14266108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:15:59  来源:igfitidea点击:

Create two Automapper maps between the same two object types

c#.netwcfautomapper

提问by Kevin Kalitowski

I am using AutoMapper in a WCF service to return Userobjects. Userhas properties such as AccountTeamswhich itself has child objects. All of the classes have AutoMapper maps.

我在 WCF 服务中使用 AutoMapper 来返回User对象。 User具有诸如AccountTeams本身具有子对象之类的属性。所有的类都有 AutoMapper 映射。

Depending on the WCF OperationContractthat is called, I want to return different amounts of data. I want one OperationContractto return the Userobject without its AccountTeamsproperty (and their children) populated and another OperationContractto return the Userwith the whole chain of properties filled out.

根据OperationContract调用的 WCF ,我想返回不同数量的数据。我希望一个OperationContract返回User没有AccountTeams填充其属性(及其子项)的对象,另一个OperationContract返回填充User了整个属性链的对象。

Is there a way to have two different maps between the same two objects or do I need to perform the full mapping and nullout the properties I don't want to return from the service?

有没有办法在相同的两个对象之间使用两个不同的映射,或者我是否需要执行完整映射并null删除我不想从服务返回的属性?

采纳答案by Simon Tewsi

Kevin Kalitowski raised a good point about wal's answer: If we need two configurations to deal with a mapping that needs to be different, then don't we have to duplicate all the other mappings that are common?

Kevin Kalitowski 对 wal 的回答提出了一个很好的观点:如果我们需要两个配置来处理需要不同的映射,那么我们是否不必复制所有其他常见的映射?

I think I've found a way around this using profiles: Have one profile for each of the unique mappings, and a third profile for the common mappings. Then create two configurations, one for each unique profile but also add the common profile to each configuration as well.

我想我已经找到了一种使用配置文件解决此问题的方法:为每个唯一映射设置一个配置文件,为通用映射设置第三个配置文件。然后创建两个配置,一个用于每个唯一的配置文件,但也将通用配置文件添加到每个配置中。

Example, in AutoMapper 4.2:

例如,在 AutoMapper 4.2 中:

The classes to be mapped: User and Vehicle:

要映射的类:用户和车辆:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Vehicle
{
    public int FleetNumber { get; set; }
    public string Registration { get; set; }
}

The profiles:

简介:

public class Profile1 : Profile
{
    protected override void Configure()
    {
        base.CreateMap<User, User>();
    }
}

public class Profile2 : Profile
{
    protected override void Configure()
    {
        base.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
    }
}

public class CommonProfile : Profile
{
    protected override void Configure()
    {
        base.CreateMap<Vehicle, Vehicle>();
    }
}

Then create the configurations and map the objects:

然后创建配置并映射对象:

[TestMethod]
public void TestMethod()
{
    var user = new User() { Name = "John", Age = 42 };
    var vehicle = new Vehicle {FleetNumber = 36, Registration = "XYZ123"};

    var configuration1 = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<CommonProfile>();
        cfg.AddProfile<Profile1>();
    });

    var mapper1 = configuration1.CreateMapper();
    var mappedUser1 = mapper1.Map<User, User>(user);//maps both Name and Age
    var mappedVehicle1 = mapper1.Map<Vehicle, Vehicle>(vehicle);//Maps both FleetNumber 
                                                                //and Registration.

    var configuration2 = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<CommonProfile>();
        cfg.AddProfile<Profile2>();
    });

    var mapper2 = configuration2.CreateMapper();
    var mappedUser2 = mapper2.Map<User, User>(user);//maps only Name
    var mappedVehicle2 = mapper2.Map<Vehicle, Vehicle>(vehicle);//Same as mappedVehicle1.
}

I tried this out and it works.

我试过了,它有效。

回答by mrtentje

I think you can solve this problem with different Configuration objects as described here, you can find an example of this here

我想你可以解决这个问题有不同的配置对象所描述的 在这里,你可以找到这样的例子在这里

回答by wal

I am assuming you are mapping from Userto User(if not then just change the destination type)

我假设您正在映射UserUser(如果不是,则只需更改目标类型)

Assume this class for the following example:

假设这个类用于以下示例:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

You can then use separate AutoMapper.Configurationto define 2 maps:

然后您可以使用单独的AutoMapper.Configuration来定义 2 个地图:

[TestMethod]
public void TestMethod()
{
    var configuration1 = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
    var mapper1 = new MappingEngine(configuration1);
    configuration1.CreateMap<User, User>();

    var user = new User() { Name = "John", Age = 42 };
    var mappedUser1 = mapper1.Map<User, User>(user);//maps both Name and Age

    var configuration2 = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
    configuration2.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
    var mapper2 = new MappingEngine(configuration2);

    var mappedUser2 = mapper2.Map<User, User>(user);
    Assert.AreEqual(0, mappedUser2.Age);//maps only Name
}

To avoid mapping every other Type twice you could add a common method that takes a Configurationwhich maps everything that can be reached from Userand call this on both configuration1and configuration2after the calls to CreateMap.

为了避免映射所有其他类型的两倍,你可以添加需要的常用方法Configuration,其映射,可以从到达的一切User,并呼吁这两个configuration1configuration2呼叫后CreateMap

Update

更新

For Automapper 4.x use the following:

对于 Automapper 4.x,请使用以下内容:

var configuration1 = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<User, User>();
});

var mapper1 = configuration1.CreateMapper();
var user = new User() { Name = "John", Age = 42 };
var mappedUser1 = mapper1.Map<User, User>(user);//maps both Name and Age

var configuration2 = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
});

var mapper2 = configuration2.CreateMapper();
var mappedUser2 = mapper2.Map<User, User>(user);   //maps only Name