【问题标题】:Reuse existing nested class instances with AutoMapper使用 AutoMapper 重用现有的嵌套类实例
【发布时间】:2016-11-26 12:56:56
【问题描述】:

我已经在 SO & Google 上查看过类似的问题,但找不到答案。这段代码应该显示我当前的场景:

class Entity
{
  Guid EntityId { get; set; }
  string EntityName { get; set; }
  NestedEntity Nested { get; set; }
  // more domain methods
}

class NestedEntity
{
  Guid NestedId { get; set; }
  string NestedName { get; set; }
  string NestedDescription { get; set; }
  // more domain methods
}

class EntityDto
{
  Guid EntityId { get; set; }
  string EntityName { get; set; }
  NestedEntityDto Nested { get; set; }
}

class NestedEntityDto
{
  Guid NestedId { get; set; }
  string NestedName { get; set; }
  string NestedDescription { get; set; }
}

class MyMappingProfile : Profile
{
  CreateMap<Entity, EntityDto>();
  CreateMap<NestedEntity, NestedEntityDto>();
}

// that profile gets added to configuration, not shown here
// IMapper is registered and injected as a dependency, not shown here

EntityDto entityDto = GrabFromEntityFrameworkDbContext();

Entity entity = GrabChangesByUser();

mapper.Map<Entity, EntityDto>(entity, entityDto);

因此,这是关于使用用户所做的更改来更新已保存在数据库中的现有项目。 EntityDto 实例取自实体框架,其中 DbContext 将开始跟踪 EntityDtoNestedEntityDtoEntity 实例包含用户所做的更改,例如通过 MVC/API PUT 操作。

mapper.Map&lt;Entity, EntityDto&gt;(entity, entityDto); 代表一种快速(针对开发人员)将Entity 深度克隆到EntityDto 的现有实例中的方法。

问题是第一级实体的实例实际上被重用了(entityDto),但嵌套的实体实例不会发生同样的情况。从我当前的测试中,NestedEntityDto 的新实例被创建并分配给EntityDto。这搞砸了 EF 更改跟踪,因为现在有两个嵌套的实体实例具有相同的 ID,等等。

那么:我如何让 AutoMapper 不仅为第一级目标对象重用同一个实例,而且还为它的嵌套属性重用相同的实例?有没有办法做到这一点?谢谢大家

环境:ASP.NET Core 1.0、EF Core 1.0、AutoMapper 5.0.2、C#6

【问题讨论】:

  • 您可能需要编写自定义值解析器
  • 幸运的是,吉米刚刚在Automapper and ASP.NET Core 1上写了一篇文章
  • 感谢您的反馈。是的,我知道那篇文章,并且在 Net Core 中的集成不是问题,这是可行的。您能否详细说明您的价值解析器想法?我们已经在使用一个将某个字段转换为另一个字段。但我看不出它如何允许您重用顶层以下的现有实例。
  • 嗯,想了想。您应该使用工具来使您的工作更快更容易,如果您觉得它太难了,那么只需使用自动映射器来映射值类型属性并将复杂的对象留给手动映射!我一直这样做,没问题

标签: c# entity-framework automapper


【解决方案1】:

暂时我的解决方案基本上是放弃使用 AutoMapper 来映射顶级类(Entity & EntityDto),同时继续使用它来映射嵌套类。

在我的场景中,顶级类有一些属性,而有更多的嵌套类有自己的属性,所以我的 be-lazy 平衡让我拥有了一个用于手动映射的自定义映射器顶级类并手动保留实例。这需要一个 IMapper 依赖项来映射嵌套类并在需要时重用现有实例。

当然,这种方法有效,因为我只对在顶级和第一嵌套级别保留实例感兴趣。同样,如果我必须在更下面的级别上保留实例,它也行不通。

编辑:几个月后...
我再次遇到了同样的问题,这次至少可以在 SO 上找到一些可能的解决方法。对于未来的读者:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 2023-04-03
    • 2010-12-06
    • 2015-02-18
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    相关资源
    最近更新 更多