【问题标题】:Making AutoMapper reuse previously mapped instances使 AutoMapper 重用以前映射的实例
【发布时间】:2019-12-11 21:27:41
【问题描述】:

我希望 AutoMapper 将相同的对象实例 Source 映射到相同的 Target 实例。

我确信 AutoMapper 可以配置为执行此操作,但是如何配置?我需要将对象图 A 转换为 B,保留映射对象之间的引用。

例如,这会失败:

[Fact]
public void Same_instances_are_mapped_to_same_instances()
{
    var configuration = new MapperConfiguration(config => config.CreateMap<Source, Target>());
    var mapper = configuration.CreateMapper();

    var source = new Source();
    var list = mapper.Map<IEnumerable<Target>>(new[] { source, source, source });

    list.Distinct().Should().HaveCount(1);
}

public class Source
{
}

public class Target
{   
}

它想通过这个测试。

另外,请注意映射器应该“记住”在当前Map 调用期间映射的实例。

【问题讨论】:

  • 你的测试本质上是错误的,那么你为什么要试图让它通过呢? Distinct() 将检查参考差异,因此测试失败。您可以使用自定义 IEqualityComparer&lt;Target&gt; 通过一些自定义业务逻辑来评估相等性。
  • 抱歉,但我的测试特别正确且符合我的预期。 A 的相同实例,B 的相同实例。这正是我要问的。
  • @Gleb 是的。我需要在对象图中保持参照完整性。因此,如果 A 持有对 B 的引用,mappedA 应该持有对 mappedB 的引用。
  • 您的测试是建立在您认为 Automapper 应该如何工作的前提下,而不是它如何工作。您可能需要完全使用转换器或自定义代码的自定义 Automapper 逻辑。
  • 设置PreserveReferences.

标签: c# .net automapper


【解决方案1】:

这是你能得到的最近的:

public static class Program
{
    public static void Main()
    {
        var config = new MapperConfiguration(conf => conf.CreateMap<Source, Target>().PreserveReferences());
        var mapper = config.CreateMapper();

        var source = new Source();
        var list = new[] { source, source, source };
        var firstRun = mapper.Map<IEnumerable<Target>>(list);
        var secondRun = mapper.Map<IEnumerable<Target>>(list);

        // Returns two items
        var diffs = firstRun.Concat(secondRun).Distinct();

        foreach (var item in diffs)
        {
            Console.WriteLine(item.Id);
        }
    }
}

public class Source
{
    public Guid Id { get; } = Guid.NewGuid();
}

public class Target
{
    public string Id { get; set; }
}

这意味着,在每次调用 mapper.Map() 的情况下,您只能取回相同的项目,但如果您多次调用映射器,每次调用都会取回新的项目(这是有道理的,否则mapper 必须在其整个生命周期内保存对所有给定和创建实例的引用,这可能会导致一些严重的内存问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    相关资源
    最近更新 更多