. Net Ядро, возвращающее список из 2 разных объектов с несколькими свойствами, связанными друг с другом. - PullRequest
0 голосов
/ 15 апреля 2020

У меня проблемы с возвратом списка объектов, которые находятся внутри класса. Эти объекты различны: один представляет собой список User объектов, который содержит несколько свойств, а другой - KanbanTask, который имеет свои собственные свойства.

User и KanbanTask связаны в базе данных с отношением «многие ко многим». Я хочу вернуть список всех KanbanTasks с их свойствами и дополнительный список пользователей, подключенных к этой задаче. Я использую шаблон репозитория, и репозиторий, и контроллер работают нормально, проблема в классе обслуживания. Visual Studio не отображает никаких ошибок, но при тестировании на swagger не работает и показывает ошибки.

Вот мой код:

public async Task<TaskWithUserListDTO> GetAllUsersPerTask()
{
    var list = await _taskrepo.GetAll(y => y.Id);
    var userTaskList = await _usertaskrepo.GetAll(x => x.User, y => y.KanbanTask);

    List<TaskWithUserDTO> newList = new List<TaskWithUserDTO>();

    foreach (KanbanTask task in list)
    {
        var ifHasUser = await _usertaskrepo.GetSingleEntity(x => x.KanbanTaskId == task.Id);

        if (ifHasUser == null)
        {
            newList.Add(new TaskWithUserDTO
                            {
                                KanbanTask = task,
                                UserList = new List<User>()
                            });
        }
        else
        {
            List<User> finalList = new List<User>();

            foreach (UserTask userTask in userTaskList)
            {
                if (userTask.KanbanTaskId == task.Id)
                {
                    var user = await _repo.GetSingleEntity(x => x.Id == userTask.UserId);
                    finalList.Add(user);
                }
            }

            newList.Add(new TaskWithUserDTO
                            {
                                 KanbanTask = task,
                                 UserList = finalList
                            });
        }
    }

    var userList = new TaskWithUserListDTO() { TaskWithUserList = newList };
    return userList;
}

Вот две модели, которые я использую для этой модели

namespace Kanban.Model.Models.Response
{
    public class TaskWithUserDTO
    {
        public KanbanTask KanbanTask { get; set; }
        public List<User> UserList { get; set; }
    }

    public class TaskWithUserListDTO
    {
        public List<TaskWithUserDTO> TaskWithUserList { get; set; }
    }
}

User и KanbanTask (Entity - модель с только Id):

public class User : Entity
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Surname { get; set; }
}

public class KanbanTask : Entity
{
    public string Title { get; set; }
    [Required]
    public string Description { get; set; }
    [Required] 
    public string Status { get; set; }
    public int ProgressStatus { get; set; }
}

Класс, который связывает эти модели

public class UserTask : Entity
{
    public int UserId { get; set; }
    public User User { get; set; }
    public int KanbanTaskId { get; set; }
    public KanbanTask KanbanTask { get; set; }
}

Конечный результат должен выглядеть следующим образом (если для задачи назначено более 1 пользователя, то в списке будет отображаться несколько пользователей, если его нет, то будет пустой список

"List": [
{
"kanbanTask": 
        {
          "title": "string",
          "description": "string",
          "status": "string",
          "progressStatus": 2,
          "id": 1
},
"userList" :
    {
    "name": "string",
        "surname": "string",
        "id": 1
}]

Ошибка от чванства :

System.InvalidOperationException: Lambda expression used inside Include is not valid.
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessInclude(NavigationExpansionExpression source, Expression expression, Boolean thenInclude)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IncludableQueryable`2.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Kanban.Repository.Repository`1.GetAll(Expression`1[] includes) in C:\Users\Igor\Desktop\Projekt Kanban\Projekt Kanban\Kanban.Repository\Repository.cs:line 56
   at Kanban.Service.UserService.GetAllUsersPerTask() in C:\Users\Igor\Desktop\Projekt Kanban\Projekt Kanban\Kanban.Services\UserService.cs:line 216
   at Projekt_Kanban.Controllers.UserController.GetAllUsersPerTask() in C:\Users\Igor\Desktop\Projekt Kanban\Projekt Kanban\Projekt Kanban\Controllers\UserController.cs:line 97
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7,uk-UA;q=0.6,uk;q=0.5,ru;q=0.4,de;q=0.3
Connection: close
Host: localhost:44346
Referer: https://localhost:44346/swagger/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
...