Automapper 无法创建具有两个不同实体的地图

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

下面是两个实体

public class User
    {
        public int UId { get; set; }

        public string UName { get; set; } = null!;

        public string UUsername { get; set; } = null!;

        public string UPassword { get; set; } = null!;

        public string? UEmail { get; set; }

        public int ULevel { get; set; }

        public int? UAddBy { get; set; }

        public DateTime? UAddDate { get; set; }

        public int? ULastEditBy { get; set; }

        public DateTime? ULastEditDate { get; set; }

        public string? UActive { get; set; }
    }

    public class UsersProvider
    {
        public int UpId { get; set; }

        public int UpUserId { get; set; }

        public int? UpProvId { get; set; }

        public int? UpAddBy { get; set; }

        public DateTime? UpAddDate { get; set; }
    }

And below DTO for which has combined entities response 

 public class GetLoginResponse
    {
        public string? Active { get; set; }
        public string Password { get; set; }
        public int UserID { get; set; }
        public int Level { get; set; }
        public string Name { get; set; }
        public int? RecruitmentCenterID { get; set; }
    }

下面是映射器类

public class GetLoginResponseMapper: Profile
    {
        public GetLoginResponseMapper()
        {
            //CreateMap<User, GetLoginResponse>(MemberList.Source);
            //CreateMap<UsersProvider, GetLoginResponse>(MemberList.Source)
            //      .ForMember(d => d.RecruitmentCenterID, a => a.MapFrom(s => s.UpProvId));

            //CreateMap<GetLoginResponse, (User, UsersProvider)>(MemberList.Destination)
            //       .ForMember(x => x.Item1, opts => opts.MapFrom(x => x))
            //       .ForMember(x => x.Item2, opts => opts.MapFrom(x => x.RecruitmentCenterID))
            //       .ReverseMap();

            CreateMap<(User user, UsersProvider usersProvider), GetLoginResponse>()
                    .ForMember(d => d.Active, opt => opt.MapFrom(s => s.user.UActive))
                    .ForMember(d => d.Password, opt => opt.MapFrom(s => s.user.UPassword))
                    .ForMember(d => d.UserID, opt => opt.MapFrom(s => s.user.UId))
                    .ForMember(d => d.Level, opt => opt.MapFrom(s => s.user.ULevel))
                    .ForMember(d => d.Name, opt => opt.MapFrom(s => s.user.UName))
                    .ForMember(d => d.RecruitmentCenterID, a => a.MapFrom(s => s.usersProvider.UpProvId));

            //CreateMap<User, GetLoginResponse>();
        }
    }

下面是将输出映射到 GetLoginResponse 的处理程序

 public class GetLoginQueryHandler : IRequestHandler<GetLoginRequest, List<GetLoginResponse>>
    {
        private readonly ICrewApplicationDBContext _iCrewApplicationDBContext;

        private readonly IMapper _mapper;

        public GetLoginQueryHandler(ICrewApplicationDBContext iCrewApplicationDBContext, IMapper mapper)
        {
            _iCrewApplicationDBContext = iCrewApplicationDBContext;
            _mapper = mapper;
        }

        public Task<List<GetLoginResponse>> Handle(GetLoginRequest request, CancellationToken cancellationToken)
        {
            //return _iCrewApplicationDBContext.user.ProjectTo<GetLoginResponse>(_mapper.ConfigurationProvider).Where(a => a.UUsername == request.UserName).ToListAsync();

            return (from u in _iCrewApplicationDBContext.user
                    join up in _iCrewApplicationDBContext.usersProvider on u.UId equals up.UpUserId
                    into loginResult
                    from lr in loginResult.DefaultIfEmpty()
                    where u.UName == request.UserName
                    select new GetLoginResponse
                    {
                        Active = u.UActive,
                        Password = u.UPassword,
                        UserID = u.UId,
                        Level = u.ULevel,
                        Name = u.UName,
                        RecruitmentCenterID = lr.UpProvId 
                    })   
                    .ProjectTo<GetLoginResponse>(_mapper.ConfigurationProvider)
                    .ToListAsync();
        }
    }


但是当尝试从 webAPI 控制器访问此方法时出现以下异常

System.InvalidOperationException:缺少从 CrewApplication.Architecture.Application.AdminLogin.GetLoginResponse 到 CrewApplication.Architecture.Application.AdminLogin.GetLoginResponse 的映射。使用 CreateMap 创建。 在 AutoMapper.QueryableExtensions.Impl.ProjectionBuilder.CreateProjection(ProjectionRequest& 请求,LetPropertyMaps letPropertyMaps) 在 AutoMapper.QueryableExtensions.Impl.ProjectionBuilder.CreateProjection(ProjectionRequest 请求) 在 AutoMapper.Internal.LockingConcurrentDictionary

2.<>c__DisplayClass2_1.<.ctor>b__1() at System.Lazy
1.ViaFactory(LazyThreadSafetyMode 模式) 在 System.Lazy
1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy
1.CreateValue() 在 System.Lazy
1.get_Value() at AutoMapper.Internal.LockingConcurrentDictionary
2.GetOrAdd(TKey& key) 在 AutoMapper.QueryableExtensions.Impl.ProjectionBuilder.GetProjection(类型 sourceType,类型 destinationType,对象参数,MemberPath [] membersToExpand) 在 AutoMapper.QueryableExtensions.Extensions.ToCore(IQueryable 源,类型 destinationType,IConfigurationProvider 配置,对象参数,IEnumerable
1 memberPathsToExpand) at AutoMapper.QueryableExtensions.Extensions.ToCore[TResult](IQueryable source, IConfigurationProvider configuration, Object parameters, IEnumerable
1 memberPathsToExpand) 在 AutoMapper.QueryableExtensions.Extensions.ProjectTo[TDestination](IQueryable source, IConfigurationProvider configuration, Object parameters, Expression
1[] membersToExpand) at AutoMapper.QueryableExtensions.Extensions.ProjectTo[TDestination](IQueryable source, IConfigurationProvider configuration, Expression
1[] membersToExpand) 在 C:\Users\VivekChavan\source 中的 CrewApplication.Architecture.Application.AdminLogin.GetLoginQueryHandler.Handle(GetLoginRequest 请求,CancellationToken cancellationToken) epos\CrewApplication.Architecture.Api\CrewApplication.Architecture.Application\AdminLogin\GetLoginQueryHandler.cs:第 32 行 在 MediatR.Wrappers.RequestHandlerWrapperImpl
2.<>c__DisplayClass1_0.<Handle>g__Handler|0() at MediatR.Wrappers.RequestHandlerWrapperImpl
2.Handle(IRequest
1 request, IServiceProvider serviceProvider, CancellationToken cancellationToken) at MediatR.Mediator.Send[TResponse](IRequest
1 请求,CancellationToken cancellationToken) 在 C:\Users\VivekChavan\source 中的 CrewApplication.Architecture.Api.Controllers.LoginController.GetAdminLoginResponseByUserNameAsync(String userName) epos\CrewApplication.Architecture.Api\CrewApplication.Architecture.Api\Controllers\LoginController.cs:第 23 行 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext,IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask`1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序、任务 lastTask、接下来的状态、范围范围、对象状态、布尔值已完成) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next、Scope& scope、Object& state、Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- 从上一个位置开始的堆栈跟踪结束 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker 调用程序、任务 lastTask、接下来的状态、范围范围、对象状态、布尔值已完成) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用程序、任务任务、IDisposable 范围) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用程序、任务任务、IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点、任务请求任务、ILogger 记录器) 在 Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext,ISwaggerProvider swaggerProvider) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext 上下文)

我尝试用不同的方法来映射这个我已经注释掉的对象。

 public GetLoginResponseMapper()
        {
            //CreateMap<User, GetLoginResponse>(MemberList.Source);
            //CreateMap<UsersProvider, GetLoginResponse>(MemberList.Source)
            //      .ForMember(d => d.RecruitmentCenterID, a => a.MapFrom(s => s.UpProvId));

            //CreateMap<GetLoginResponse, (User, UsersProvider)>(MemberList.Destination)
            //       .ForMember(x => x.Item1, opts => opts.MapFrom(x => x))
            //       .ForMember(x => x.Item2, opts => opts.MapFrom(x => x.RecruitmentCenterID))
            //       .ReverseMap();

            CreateMap<(User user, UsersProvider usersProvider), GetLoginResponse>()
                    .ForMember(d => d.Active, opt => opt.MapFrom(s => s.user.UActive))
                    .ForMember(d => d.Password, opt => opt.MapFrom(s => s.user.UPassword))
                    .ForMember(d => d.UserID, opt => opt.MapFrom(s => s.user.UId))
                    .ForMember(d => d.Level, opt => opt.MapFrom(s => s.user.ULevel))
                    .ForMember(d => d.Name, opt => opt.MapFrom(s => s.user.UName))
                    .ForMember(d => d.RecruitmentCenterID, a => a.MapFrom(s => s.usersProvider.UpProvId));

            //CreateMap<User, GetLoginResponse>();
        }
c# asp.net-core-webapi automapper .net-7.0
© www.soinside.com 2019 - 2024. All rights reserved.