I use mapster to map my db model and dto object mapping, but i getting some projection error.
I set mapster global config like this:
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
My db model and dto classes are like this:
public class AdapterMessage : BaseEntity<Guid>, IAggregateRoot
{
public string MessageID { get; set; }
public string? MessageKey { get; set; }
public string? ScenarioIdentifier { get; set; }
public string? SenderName { get; set; }
public string? ReceiverName { get; set; }
public string? InterfaceName { get; set; }
public string? Namespace { get; set; }
public string? ErrorLabel { get; set; }
public string? ErrorCode { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public DateTime? PersistUntil { get; set; }
public DateTime? ValidUntil { get; set; }
public string? MessageType { get; set; }
public string? NodeId { get; set; }
public string? QualityOfService { get; set; }
public string? Status { get; set; }
public string Size { get; set; }
public bool? Cancelable { get; set; }
public string? ConnectionName { get; set; }
public string? Credential { get; set; }
public string? Direction { get; set; }
public bool? Editable { get; set; }
public string? Endpoint { get; set; }
public string? Headers { get; set; }
public string? IsPersistent { get; set; }
public string? Protocol { get; set; }
public string? ReceiverInterfaceName { get; set; }
public string? ReceiverInterfaceNameSpace { get; set; }
public string? ReceiverPartyAgency { get; set; }
public string? ReceiverPartyName { get; set; }
public string? ReceiverPartySchema { get; set; }
public bool? Restartable { get; set; }
public string? Retries { get; set; }
public string? RetryInterval { get; set; }
public string? SenderInterfaceName { get; set; }
public string? SenderInterfaceNameSpace { get; set; }
public string? SenderPartyAgency { get; set; }
public string? SenderPartyName { get; set; }
public string? SenderPartySchema { get; set; }
public string? SequenceNumber { get; set; }
public string? SerializationContext { get; set; }
public string? TimesFailed { get; set; }
public string? Version { get; set; }
public bool? WasEdited { get; set; }
public string? PayloadPermissionWarning { get; set; }
public string? Duration { get; set; }
public string? MessagePriority { get; set; }
public string? MessageListBytesXmlAM { get; set; }
public string? MessageListBytesXmlBI { get; set; }
public string? MessageListBytesXmlMS { get; set; }
public string? MessageListBytesXmlSC { get; set; }
public bool? IsMessageListBytesWritter { get; set; }
public DateTime? LastAuditLogQueryDate { get; set; }
public List<AdapterMessageAuditLog> AdapterMessageAuditLogs { get; set; }
}
My Dto class like this:
using Application.Sap.AdapterMessageAuditLog;
using Domain.Common.Contracts;
namespace Application.Sap.AdapterMessage
{
public class AdapterMessageDto : BaseDto
{
public string MessageID { get; set; }
public string? MessageKey { get; set; }
public string? ScenarioIdentifier { get; set; }
public string? SenderName { get; set; }
public string? ReceiverName { get; set; }
public string? InterfaceName { get; set; }
public string? Namespace { get; set; }
public int? ErrorLabel { get; set; }
public string? ErrorCode { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public DateTime? PersistUntil { get; set; }
public DateTime? ValidUntil { get; set; }
public string? MessageType { get; set; }
public int? NodeId { get; set; }
public string? QualityOfService { get; set; }
public string? Status { get; set; }
public long Size { get; set; }
public bool? Cancelable { get; set; }
public string? ConnectionName { get; set; }
public string? Credential { get; set; }
public string? Direction { get; set; }
public bool? Editable { get; set; }
public string? Endpoint { get; set; }
public string? Headers { get; set; }
public bool? IsPersistent { get; set; }
public string? Protocol { get; set; }
public string? ReceiverInterfaceName { get; set; }
public string? ReceiverInterfaceNameSpace { get; set; }
public string? ReceiverPartyAgency { get; set; }
public string? ReceiverPartyName { get; set; }
public string? ReceiverPartySchema { get; set; }
public bool? Restartable { get; set; }
public int? Retries { get; set; }
public int? RetryInterval { get; set; }
public string? SenderInterfaceName { get; set; }
public string? SenderInterfaceNameSpace { get; set; }
public string? SenderPartyAgency { get; set; }
public string? SenderPartyName { get; set; }
public string? SenderPartySchema { get; set; }
public int? SequenceNumber { get; set; }
public string? SerializationContext { get; set; }
public int? TimesFailed { get; set; }
public int? Version { get; set; }
public bool? WasEdited { get; set; }
public string? PayloadPermissionWarning { get; set; }
public long Duration { get; set; }
public int? MessagePriority { get; set; }
public string? MessageListBytesXmlAM { get; set; }
public string? MessageListBytesXmlBI { get; set; }
public string? MessageListBytesXmlMS { get; set; }
public string? MessageListBytesXmlSC { get; set; }
public bool? IsMessageListBytesWritter { get; set; }
public DateTime? LastAuditLogQueryDate { get; set; }
public List<AdapterMessageAuditLogDto> AdapterMessageAuditLogs { get; set; }
}
}
When i comment public List<AdapterMessageAuditLogDto> AdapterMessageAuditLogs { get; set; }
property, everything works fine, but if i want to map this property then getting this error:
Error while compiling\nsource=Domain.Entity.SAP.AdapterMessage\ndestination=Application.Sap.AdapterMessage.AdapterMessageDto\ntype=Projection
I use ardalis specifiaction, so i use mapster method in my repository like this:
using Application.Common.Persistence;
using Ardalis.Specification;
using Ardalis.Specification.EntityFrameworkCore;
using Domain.Common.Contracts;
using Domain.Entity.Configuration;
using Infrastructure.Persistance.Context;
using Mapster;
using Microsoft.EntityFrameworkCore.Storage;
namespace Infrastructure.Persistance.Repository
{
// Inherited from Ardalis.Specification's RepositoryBase<T>
public class ApplicationDbRepository<T> : RepositoryBase<T>, IReadRepository<T>, IRepository<T>
where T : class, IAggregateRoot
{
private readonly ApplicationDbContext _context;
public ApplicationDbRepository(ApplicationDbContext dbContext)
: base(dbContext)
{
_context = dbContext;
}
// We override the default behavior when mapping to a dto.
// We're using Mapster's ProjectToType here to immediately map the result from the database.
// This is only done when no Selector is defined, so regular specifications with a selector also still work.
protected override IQueryable<TResult> ApplySpecification<TResult>(ISpecification<T, TResult> specification) =>
specification.Selector is not null
? base.ApplySpecification(specification)
: ApplySpecification(specification, false)
.ProjectToType<TResult>();
public IDbContextTransaction BeginTransaction() => _context.Database.BeginTransaction();
}
}
I resolved the problem. You see, entities are recursively referencing each other so Mapster tries to map every object. To stop that, you must set the max depth value.
For more: Mapster Object Reference