我已经使用 .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 数据。
我错过了什么吗?请帮忙。
执行此操作的最新方法是使用
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