I am having a stackoverlow issue during the object mapper with DTO object I want to make sure my dto class is correct.
Here is the query.
public async Task<CreateOrEditOrderDto> GetOrderForEditByPaymentyId(string paymentId)
{
var order = await _orderRepository
.GetAll()
.Include(o => o.OrderDetails)
.Include(r => r.Rewards)
.Include(p => p.OrderPromotions)
.SingleAsync(x => x.PaymentId == paymentId);
return ObjectMapper.Map<CreateOrEditOrderDto>(order); <==========================Here is the stack overflow error--because order detail has order relationship which keeps loading recursive. How can i avoid it. See my class definition below.
}
[Table("Orders")]
public class Order : FullAuditedEntity
{
[ForeignKey("ShowId")]
public virtual Events.Show.Show Show { get; set; }
public virtual int ShowId { get; set; }
..
..
public virtual OrderStatus OrderStatus { get; set; }
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
public virtual ICollection<Reward.Reward> Rewards { get; set; }
public virtual ICollection<OrderPromotion> OrderPromotions { get; set; }
}
public class OrderDetail : Entity<int>
{
[ForeignKey("OrderId")]
public virtual Events.Order.Order Order { get; set; }
public virtual int OrderId { get; set; }
[Required]
public virtual int ShowTicketId { get; set; }
public virtual string TicketName { get; set; }
public virtual int TicketCount { get; set; }
public virtual double TotalTicketAmount { get; set; }
}
public class OrderDetailDto : EntityDto
{
public CreateOrEditOrderDto Order { get; set; }
public int OrderId { get; set; }
public int ShowTicketId { get; set; }
public string TicketName { get; set; }
public int TicketCount { get; set; }
public double TotalTicketAmount { get; set; }
}
public class CreateOrEditOrderDto : FullAuditedEntityDto<int?>
{
public CreateOrEditShowDto Show { get; set; }
[Required]
public int ShowId { get; set; }
..
..
public ICollection<OrderDetailDto> OrderDetails { get; set; }
public ICollection<RewardDto> Rewards { get; set; }
public ICollection<OrderPromotionDto> OrderPromotions { get; set; }
}
12 Answer(s)
-
0
You have self-referencing DTOs.
refer:https://stackoverflow.com/questions/37251043/automapper-throwing-stackoverflowexception-when-calling-projecttot-on-iquery?answertab=votes#tab-top
-
0
i looked at the link above and i wanted to follow this option CreateMap<AppUser, AppUserDTO>().MaxDepth(3); how do i set the maxdepth in my abp objectmapper?
-
0
I recommend that you do not use self-referencing in Dto.
-
0
ok i found the customdtomapper.cs and i changed the following line in my code to use maxdepth(1)
configuration.CreateMap<CreateOrEditOrderDto, Order.Order>().ForMember(x => x.CreatorUserId, opt => opt.Ignore()).MaxDepth(1);
I still have stackoverflow issue on the same line as i mentioned earlier. What am i missing?
-
0
It is not self referencing DTO. The child table is referencing the parent table. Please look at my class model above.
-
0
my model design is basically same as "convention 4" mentioned in this link http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx
-
0
the problem is, the dto that has to match exactly as class design otherwise i am getting "AutoMapperMappingException" How can i avoid reference in dto object alone?
-
0
here is the dto and the class model for example In the following dto, i removed the order reference and get the error.
public class OrderDetail : Entity<int> { [ForeignKey("OrderId")] public virtual Events.Order.Order Order { get; set; } public virtual int OrderId { get; set; } [Required] public virtual int ShowTicketId { get; set; } public virtual string TicketName { get; set; } public virtual int TicketCount { get; set; } public virtual double TotalTicketAmount { get; set; } }
public class CreateOrEditOrderDetailDto : Entity<int> { [Required] public int OrderId { get; set; }
[Required] public int ShowTicketId { get; set; } public string TicketName { get; set; } public int TicketCount { get; set; } public double TotalTicketAmount { get; set; } }
-
0
Dto does not have to be consistent with the entity.
You can look at the Dto class code in Zero.Low-level (child) Dto does not reference the superior (parent) Dto
https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application.Shared/Authorization/Users/Dto/GetUserForEditOutput.cs https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application.Shared/Authorization/Users/Dto/UserEditDto.cs https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application.Shared/Authorization/Users/Dto/UserRoleDto.cs
-
0
I will give a try. thanks
-
0
Nope. i get the following error if the dto is different than the class.
AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types: CreateOrEditOrderDto -> Order Events.Order.Dtos.CreateOrEditOrderDto -> Events.Order.Order
Type Map configuration: CreateOrEditOrderDto -> Order Events.Order.Dtos.CreateOrEditOrderDto -> Events.Order.Order
Property: OrderDetails ---> AutoMapper.AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters ========================================================================= CreateOrEditOrderDetailDto -> OrderDetail (Destination member list) Events.Order.Dtos.CreateOrEditOrderDetailDto -> Events.Order.OrderDetail (Destination member list)
Unmapped properties: Order
at AutoMapper.ConfigurationValidator.AssertConfigurationIsValid(IEnumerable`1 typeMaps) at lambda_method(Closure , CreateOrEditOrderDto , Order , ResolutionContext ) --- End of inner exception stack trace --- at lambda_method(Closure , CreateOrEditOrderDto , Order , ResolutionContext ) at lambda_method(Closure , Object , Object , ResolutionContext ) at AutoMapper.Mapper.AutoMapper.IMapper.Map[TDestination](Object source) at Events.Order.OrdersAppService.Create(CreateOrEditOrderDto input) in C:\Kumaran\AspnetZero\Events\aspnet-core\src\Events.Application\Order\OrdersAppService.cs:line 352 at Events.Order.OrdersAppService.CreateOrEdit(CreateOrEditOrderDto input) in C:\Kumaran\AspnetZero\Events\aspnet-core\src\Events.Application\Order\OrdersAppService.cs:line 341 at Events.MultiTenancy.Payments.PaymentAppService.CreateShowPayment(ShowPaymentInfoInput input) in C:\Kumaran\AspnetZero\Events\aspnet-core\src\Events.Application\MultiTenancy\Payments\PaymentAppService.cs:line 148 at lambda_method(Closure , Object ) at Mic...
-
1
found the fix. I have to ignore those attributes in CustomDtoMapper.cs that are not required to be mapped. In my case the order object in the order child tables needs to be ignored otherwise you get into recursive relationship.
configuration.CreateMap<CreateOrEditOrderDetailDto, OrderDetail>().ForMember(x => x.Order, opt => opt.Ignore()); configuration.CreateMap<CreateOrEditRewardDto, Reward.Reward>().ForMember(x => x.Order, opt => opt.Ignore()); configuration.CreateMap<CreateOrEditOrderPromotionDto, OrderPromotion>().ForMember(x => x.Order, opt => opt.Ignore());