Base solution for your next web application
Open Closed

ObjectMapper List mapping #5539


User avatar
0
ice2burn created

Hi,

Trying to map list to my model using ObjectMapper.

public class GetTicketForView
    {
        public TicketDto Ticket { get; set; }
        public string TenantName { get; set; }
        public string ProductName { get; set;}
        public string ProductVersionName { get; set;}
        public TicketStateTableDto TicketState { get; set; }
        public string TicketTypeName { get; set;}
        public string TicketPriorityName { get; set;}
        public List<TicketLinkedUserDto> LinkedUsers { get; set; } // <--
    }

TicketLinkedUsers is many to many relation.

AppService:

. . .
var query = (from o in filteredTickets
             join o1 in _productRepository.GetAll() on o.ProductId equals o1.Id into j1
             from s1 in j1.DefaultIfEmpty()
             join o2 in _productVersionRepository.GetAll() on o.ProductVersionId equals o2.Id into j2
             from s2 in j2.DefaultIfEmpty()
             join o3 in _ticketTypeRepository.GetAll() on o.TicketTypeId equals o3.Id into j3
             from s3 in j3.DefaultIfEmpty()
             join o4 in _ticketPriorityRepository.GetAll() on o.TicketPriorityId equals o4.Id into j4
             from s4 in j4.DefaultIfEmpty()
             join o5 in _ticketStateRepository.GetAll() on o.TicketStateId equals o5.Id into j5
             from s5 in j5.DefaultIfEmpty()
             join o6 in _tenantManager.Tenants on o.TenantId equals o6.Id into j6
             from s6 in j6.DefaultIfEmpty()
             join o7 in _ticketLinkedUsersRepository.GetAll() on o.Id equals o7.TicketId into j7
             from s7 in j7.DefaultIfEmpty()
             select new GetTicketForView() { Ticket = ObjectMapper.Map<TicketDto>(o)
        , ProductName = s1 == null ? "" : s1.Name.ToString()
        , ProductVersionName = s2 == null ? "" : s2.Name.ToString()
        , TicketTypeName = s3 == null ? "" : s3.Name.ToString()
        , TicketPriorityName = s4 == null ? "" : s4.Name.ToString()
        , TicketState = ObjectMapper.Map<TicketStateTableDto>(s5)
        , TenantName = s6 == null ? "" : s6.Name.ToString()
        , LinkedUsers = ObjectMapper.Map<List<TicketLinkedUserDto>>(s7) // <--
});

But it fails with:

Unmapped properties: Capacity


4 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    s7 is not a List.

  • User Avatar
    0
    ice2burn created

    You are right, it should be J7.

    However I get different error in log:

    INFO  2018-08-24 13:30:05,375 [21   ] ore.Mvc.Internal.ControllerActionInvoker - Executing action method Fansy.IdentityServer.Tickets.TicketsAppService.GetAll (Fansy.IdentityServer.Application) with arguments (Fansy.IdentityServer.Tickets.Dtos.GetAllTicketsInput) - Validation state: Valid
    ERROR 2018-08-24 13:30:24,275 [3    ] Mvc.ExceptionHandling.AbpExceptionFilter - Incorrect number of arguments supplied for call to method 'System.Threading.Tasks.Task`1[System.Boolean] MoveNext(System.Threading.CancellationToken)'
    Parameter name: method
    System.ArgumentException: Incorrect number of arguments supplied for call to method 'System.Threading.Tasks.Task`1[System.Boolean] MoveNext(System.Threading.CancellationToken)'
    Parameter name: method
       at System.Dynamic.Utils.ExpressionUtils.ValidateArgumentCount(MethodBase method, ExpressionType nodeKind, Int32 count, ParameterInfo[] pis)
       at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method)
       at AutoMapper.Internal.ExpressionFactory.ForEach(Expression collection, ParameterExpression loopVar, Expression loopContent)
       at AutoMapper.Mappers.Internal.CollectionMapperExpressionFactory.MapCollectionExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Type ifInterfaceType, MapItem mapItem)
       at AutoMapper.Mappers.CollectionMapper.MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
       at AutoMapper.MapperConfiguration.GenerateObjectMapperExpression(MapRequest mapRequest, IObjectMapper mapperToUse, MapperConfiguration mapperConfiguration)
       at AutoMapper.MapperConfiguration.BuildExecutionPlan(MapRequest mapRequest)
       at AutoMapper.MapperConfiguration.CreateMapperFuncs(MapRequest mapRequest)
       at AutoMapper.LockingConcurrentDictionary`2.&lt;&gt;c__DisplayClass2_1.&lt;.ctor&gt;b__1()
       at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
       at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
       at System.Lazy`1.CreateValue()
       at AutoMapper.MapperConfiguration.GetUntypedMapperFunc(MapRequest mapRequest)
       at AutoMapper.Mapper.AutoMapper.IMapper.Map[TDestination](Object source)
       at lambda_method(Closure , TransparentIdentifier`2 )
       at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken)
       at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken)
       at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable`1 source, TAccumulate seed, Func`3 accumulator, Func`2 resultSelector, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)
       at Fansy.IdentityServer.Tickets.TicketsAppService.GetAll(GetAllTicketsInput input) in D:\Work\Web\FansySystems\IdentityServer\src\Fansy.IdentityServer.Application\Tickets\TicketsAppService.cs:line 142
       at lambda_method(Closure , Object )
       at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()
    INFO  2018-08-24 13:30:24,284 [3    ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'.
    
  • User Avatar
    0
    aaron created
    Support Team

    select refers to an instance in j7. You can't map the whole j7 in a select.

  • User Avatar
    0
    ice2burn created

    What a pity, it would be so elegant.

    Made it with separate query:

    foreach (var ticket in tickets)
    {
        var linkedUsers = _ticketLinkedUsersRepository.GetAllIncluding(lu => lu.TicketLinkType, lu => lu.User)
            .Where(p => p.TicketId == ticket.Ticket.Id).ToList();
        ticket.LinkedUsers = ObjectMapper.Map<List<TicketLinkedUserDto>>(linkedUsers);
     }
    

    Thanks for your help