Automapper - 如何获取连接表数据

问题描述 投票:0回答:2

我已经使用 .Net Core 7 构建了示例应用程序并尝试使用 Automapper 12.0 并陷入了这种情况。

我想对表 HutangHistory 中的值进行求和,这些值可能是从我的下面的配置中加入的:

ApplicationDbContext.cs

 modelBuilder.Entity<Hutang>()
     .HasMany(h => h.HutangHistories)
     .WithOne(hh => hh.Hutang)
     .HasForeignKey(hh => hh.HutangId)
     .IsRequired();

MappingProfile.cs

public class MappingProfiles : Profile
{
    public MappingProfiles()
    {
        CreateMap<Hutang, HutangReadDto>()
             .ForMember(dest => dest.TotalHutang, opt => opt.MapFrom(src => src.HutangHistories.Sum(hh => hh.Nominal))); // Expected this is enough.
        CreateMap<HutangReadDto, Hutang>();
    }
}

Hutang.cs

 public class Hutang
 {
     [Key]
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public Guid HutangId { get; set; }
     public int Status { get; set; }
     public ICollection<HutangHistory> HutangHistories { get;  } = new List<HutangHistory>();
     [Required]
     public Guid CreatedBy { get; set; }
     [Required]
     public DateTime CreatedAt { get; set; }
     [Required]
     public Guid UpdatedBy { get; set; }
     [Required]
     public DateTime UpdatedAt { get; set; }
 }

HutangHistory.cs

public class HutangHistory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid HistoryId { get; set; }
    public decimal Nominal { get; set; }
    public int Tipe;
    public Guid HutangId { get; set; }
    public Hutang Hutang { get; set; } = null!;
    public Guid SumberHutangId { get; set; }
    public SumberHutang SumberHutang { get; set; } = null!;
    [Required]
    public Guid CreatedBy { get; set; }
    [Required]
    public DateTime CreatedAt { get; set; }
    [Required]
    public Guid UpdatedBy { get; set; }
    [Required]
    public DateTime UpdatedAt { get; set; }
}

HutangReadDto.cs

 public class HutangReadDto
 {
     public Guid HutangId { get; set; }
     public int Status { get; set; }
     public decimal TotalHutang { get; set; }
     public Guid CreatedBy { get; set; }
     public DateTime CreatedAt { get; set; }
 }

最后是控制器:

 private readonly ILogger<HutangAPIController> _logger;
 private readonly ApplicationDbContext _dbContext;
 private readonly IMapper _mapper;

 public HutangAPIController(ILogger<HutangAPIController> logger, ApplicationDbContext dbContext, IMapper mapper)
 {
     _logger = logger;
     _dbContext = dbContext;
     _mapper = mapper;
 }

 [HttpGet]
 [ProducesResponseType(StatusCodes.Status200OK)]
 public ActionResult<IEnumerable<HutangReadDto>> GetHutangs() 
 {
     _logger.LogInformation("Menampilkan semua hutang");

     var hutangs = _mapper.Map<HutangReadDto>(_dbContext.Hutangs.ToList()); // My expactation is HutangHistories data will be retrieved but unfortunately is not.

     return Ok(hutangs);
 } 

仅供参考,映射成功,但我没有检索 HutangHistory 数据。

我错过了什么吗?请帮忙。

c# automapper
2个回答
0
投票

看起来您没有获得子对象。使用 Include 加载子对象。

您可以在这里找到问题的答案或示例:

如何在 Entity Framework 5 中包含子对象的子对象


0
投票

执行此操作的最新方法是使用

ProjectTo
,这是在 Automapper 中引入的

所以你可以像这样定义你的映射:

public class FooEntity 
{
   public int Id {get;set;}
   public int ForeignKeyId {get;set;}
   public virtual ForeignEntity ForeignEntity {get;set;}

}

public class FooDto 
{
   public int Id {get;set;}
   public int ForeignKeyId {get;set;}
   public int ForeignItemName {get;set;}
}


 profile.CreateMap<FooEntity , FooDto >()
     .ForMember(d => d.ForeignItemName , s => s.MapFrom(x => x.ForeignEntity.Name));
 ;

然后像这样查询数据库:

IQueryable<FooDto > check = _dbContext.Foos.ProjectTo<FooDto>(_mapper.ConfigurationProvider);

然后,这将根据定义的关系创建内/左连接来查询数据库。

在我的测试中,我执行了以下映射:

public class MaintenanceLogDto
{
    public int ItemCount { get; set; }

    public void Mapping(Profile profile) => 
            profile.CreateMap<MaintenanceLog, MaintenanceLogDto>()
                .ForMember(d => d.ItemCount, s=> s.MapFrom(x => x.MaintenanceLogItems.Count()));
}

然后像这样查询:

    IQueryable<MaintenanceLogDto> logs = _tenantContext.MaintenanceLogs
                                                .ProjectTo<MaintenanceLogDto>(_mapper.ConfigurationProvider);

这是 SQL 记录的结果:

  SELECT 
      (SELECT COUNT(*)
      FROM [MaintenanceLogItems] AS [m1]
      WHERE [t].[Id] = [m1].[MaintenanceLogId]) AS [ItemCount]
  FROM (
      SELECT [m].[Id]--, ""MY OTHER FIELDS""....
      FROM [MaintenanceLogs] AS [m]
  ) AS [t]

官方文档:

https://docs.automapper.org/en/stable/Queryable-Extensions.html

© www.soinside.com 2019 - 2024. All rights reserved.