0

我只是执行明确加载子实体使用的通用仓库父母使用this问题出jevelez的方法一起。循环依赖映射时,家长和孩子实体的DTO

但是现在我试图映射与其父实体DTO的沿子实体,所以我可以将它们发送到我的UI层。

这里是我的映射器目前看起来怎么样:

映射接口:

public interface IMappingService<TEntity, TDto> 
    where TEntity : class 
    where TDto : class 
{ 
    TDto EntityToDto(TEntity entity); 
    TEntity DtoToEntity(TDto dto); 
    IEnumerable<TDto> EntitiesToDtos(IList<TEntity> entities); 
    IEnumerable<TEntity> DtosToEntities(IList<TDto> dtos); 
} 

实现接口的抽象基方法:

public abstract class MapperBase<TEntity, TDto> : IMappingService<TEntity, TDto> 
    where TEntity : class 
    where TDto : class 
{ 
    public abstract TDto EntityToDto(TEntity entity); 

    public abstract TEntity DtoToEntity(TDto dto); 

    public virtual IEnumerable<TDto> EntitiesToDtos(IList<TEntity> entities) 
    { 
     return entities.Select(EntityToDto); 
    } 

    public virtual IEnumerable<TEntity> DtosToEntities(IList<TDto> dtos) 
    { 
     return dtos.Select(DtoToEntity); 
    } 
} 

这里的是实现这两个映射器以两个实体为例:

public class ParentEntityMapper : MapperBase<ParentEntity, ParentEntityDto> , IParentEntityMapper 
{ 

    private readonly IChildEntityMapper _childEntityMapper; 

    public ParentEntityMapper(IChildEntityMapper childEntityMapper) 
    { 
     _childEntityMapper = childEntityMapper; 
    } 

    public override ParentEntityDto EntityToDto(ParentEntity entity) 
    { 
     var dto = new ParentEntityDto(); 
     dto.Id = entity.Id; 
     dto.Title = entity.Title; 
     dto.Description = entity.Description; 

     if (entity.ChildEntities != null) 
     { 
      dto.ChildEntities= _childEntityMapper.EntitiesToDtos(entity.ChildEntities .ToList()).ToList(); 
     } 

     return dto; 
    } 

    public override ParentEntity DtoToEntity(ParentEntityDto dto) 
    { 
     // This is just a reverse of the above function 
    } 
} 

而子实体映射:

public class ChildEntityMapper : MapperBase<ChildEntity, ChildEntityDto>, IChildEntityMapper 
    { 
     private readonly ParentEntityMapper _parentEntityMapper; 

     public ChildEntityMapper(IParentEntityMapper parentEntityMapper) 
     { 
      _parentEntityMapper = parentEntityMapper; 
     } 
     public override ChildEntityDto EntityToDto(ChildEntity entity) 
     { 
      var dto = new ChildEntityDto(); 

      dto.Id = entity.Id; 
      dto.Description = entity.Description; 

      if (entity.ParentEntity != null) 
      { 
       dto.ParentEntity = _parentEntityMapper.EntityToDto(entity.Image); 
      } 

      return dto; 
     } 

     public override Anchor DtoToEntity(AnchorDto dto) 
     { 
      // Just a reverse of the above function 
     } 
    } 

所以,我相信大家都可以看到的循环依赖发生。过去两天我一直在为此苦恼,但我仍然非常爱好此事,迄今为止还没有能够使用谷歌解决这个问题。

我更喜欢不使用像AutoMapper和ValueInjector这样的工具,因为我在数据库和DTO之间进行了映射,而且我已经使用它来在UI层的DTO和ViewModels之间进行映射。

如果可能,我希望能够通过这种方式保持,因为有时我会请求刚子实体,并在这些情况下,我可能要与它相处的父实体两者之间的映射。

有谁知道这可以做得如何正确吗?

回答

0

经过深思熟虑之后,我决定不是让它复杂化,而是不允许通过映射程序获取子级实体与它的父级,而是在我的服务层中处理少数但特定的场景。

任何人有同样的问题还可以检查this线程我在Reddit上创造了更多的信息。

1

我想我看到你的“循环依赖”即将在这里玩,但只是要明确的,这就是我想会发生。您可以在ParentEntity上调用EntityToDto,然后在所有ChildEntity元素上调用EntityToDto。这些ChildEntity元素中的每一个都会在ParentEntity上调用EntityToDto,然后我们回到我们开始的位置。

如果这是我的建议是简单的情况:没有父子实体护理EntityToDto。我会在树的根部解决,然后让下面的所有内容继续向下解析,直到树完成。

如果您这样做,它会阻止子实体将父项分配给自己。如果你需要能够从孩子到父母的遍历,我会让父母在EntityToDto调用完成之后将其自己分配给父母。

+0

所以你说我应该分开映射父母和孩子的实体,然后再合并他们?我的理解正确吗? – grimurd

+1

两种方法:或者在_childEntityMapper.EntitiesToDto调用之后通过dto.ChildEntities循环并调用类似dto.ChildEntity [i] .Parent = dto的东西。作为替代,完全跳过_childEntityMapper.EntitiesToDto调用,循环遍历dto.ChildEntities并分别调用EntityToDto,然后将其分配。 – Andrew