Метод Linq to Entities: Select и ToListAsync - PullRequest
0 голосов
/ 15 января 2020

Я хочу получить только несколько столбцов в запросе. Я хочу выполнить этот запрос, используя сущность:

select FirstName from Employee

Однако я не могу использовать Выбрать и ToListAsyn c одновременно. Я получаю сообщение об ошибке, и похоже, что я не могу использовать оба одновременно. Есть ли другой способ сделать это?

[HttpGet]
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
{
     return await _context.Employee.Select(s => s.FirstName).ToListAsync();
}

Ответы [ 4 ]

2 голосов
/ 16 января 2020

Комментарий Герта охватил причину ошибки. Это будет связано с тем, что функция ожидает набор сущностей сущностей Employee, но вы пытаетесь просто вернуть набор имен сотрудников, используя Select(s => s.FirstName)

Если вы хотите вернуть только имена сотрудников, обновите Подпись метода к чему-то вроде:

public async Task<ActionResult<IEnumerable<string>>> GetEmployeeNames()

Как правило, подобные ситуации возникают, когда вы хотите вернуть что-то вроде результатов поиска или сводного списка. Вы не обязательно хотите возвращать все о сотрудниках (и, возможно, сериализовать связанные с ними данные) только для отображения списка имен сотрудников, из которого пользователи могут выбирать. Тем не менее, возвращение только имени сотрудника само по себе бесполезно, если вы хотите выбрать одно из них и запросить дополнительную информацию или предпринять действия против них. (Не говоря уже о том, что у вас может быть два «Питера» в качестве сотрудников ...)

В этих случаях полезно определить простую модель представления, представляющую только те данные, которые потребуются внешнему интерфейсу. Например, имя и идентификатор сотрудника:

[Serializable]
public class EmployeeSummaryViewModel
{
    public int EmployeeId { get; set; }
    public string Name { get; set; }
}

Затем метод для извлечения сотрудников:

[HttpGet]
public async Task<ActionResult<IEnumerable<EmployeeSummaryViewModels>>> GetEmployeeSummaries()
{
    return await _context.Employee
        .Select(s => new EmployeeSummaryViewModel
        {
            EmployeeId = s.EmployeeId,
            Name = s.FirstName + " " + s.LastName
        }).ToListAsync();
}

Модель представления представляет собой простой сериализуемый C# класс. Используя Select для его заполнения, EF может сгенерировать очень эффективный запрос, возвращающий только те поля, которые мы хотим. Это может включать в себя поля из связанных таблиц, таких как Роль или тому подобное, без необходимости беспокоиться об активной загрузке или сериализации всего из этих связанных таблиц.

В приведенном выше примере модель представления содержит идентификатор для каждого возвращенного сотрудника, поэтому мы при необходимости может передать этот идентификатор будущим вызовам, например, выбрать сотрудника для загрузки полного представления или выполнить какое-либо действие. Сервер также форматирует имя. В качестве альтернативы вы можете вернуть FirstName и LastName и оставить форматирование на стороне клиента.

1 голос
/ 16 января 2020

Это неправильный синтаксис. Вы просто меняете это так:

[HttpGet]
public async Task<ActionResult<IEnumerable<string>>> GetEmployee()
{
     return await _context.Employee.Select(s => s.FirstName).ToListAsync();
}

или

[HttpGet]
public async Task<IActionResult> GetEmployee()
{
     return Ok(await _context.Employee.Select(s => s.FirstName).ToListAsync());
}
1 голос
/ 16 января 2020

Поскольку ваш тип возврата - ActionResult<IEnumerable<Employee>>. Просто используйте приведенный ниже код для возврата. Список Employee

[HttpGet]
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
    {
        var result = await _context.Employee
                         .Select(s => new Employee
                         {
                             Name = s.FirstName
                         }).ToListAsync();
        return Ok(result);

    }
1 голос
/ 15 января 2020

На основании вашего кода, я думаю, вам понадобится что-то вроде этого:

[HttpGet]
public async Task<ActionResult> GetEmployee()
{
    var employeeNames = await _context.Employee.Select(s => s.FirstName).ToListAsync();
    return Ok(employeeNames);
}
...