автоматически расширять результат функции odata - PullRequest
0 голосов
/ 15 октября 2018

Я определил функцию odata для имитации $ search, которая еще не поддерживается в последней версии ядра.Я хочу вернуть базовую сущность плюс расширенную сущность, которая преобразуется в объект js для каждого человека в массиве возвращаемых значений json.

Я пытался odata/People/MyNS.Find(text='john', orderby='CreatedOn')?$expand=CurrentWork, где CurrentWork на People, но это не сработало.

Мысли о том, как это сделать?

  // my controller code for the function
  [HttpGet]
  public ActionResult<ICollection<People>> Find([FromODataUri] string text,
        [FromODataUri] string orderBy)
        {
            if (text == null || text.Length == 0)
                return Get().ToList();
            if (orderBy == null || orderBy.Length == 0)
                orderBy = "CreatedOn";
            return _db.People
                .Where(p => p.FirstName.Contains(text)
                    || p.LastName.Contains(text)
                    || p.Nickname.Contains(text))
                .OrderBy(orderBy)
                .Take(5000)
                .ToList();
        }

Регулярное расширение CurrentWork вне функционирует нормально, например odata/People?$expand=CurrentWork.

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Вот что я придумал в конце.Я заметил, что включенные сущности извлекали много данных из базы данных, поэтому я немного уменьшил нагрузку, будучи конкретным.Включая только что вытащил все, и я не мог уменьшить Include напрямую, поэтому мне пришлось использовать Select.

    [HttpGet]
    public IOrderedQueryable Find2([FromODataUri] string text,
    [FromODataUri] string orderBy)
    {
        if (orderBy == null || orderBy.Length == 0)
            orderBy = "CreatedOn DESC";
        if (text == null || text.Length == 0)
            return Get().OrderBy(orderBy);
        var r = LikeToRegular(text);
        return _db.People
        .AsNoTracking() // can't use if using lazy loading
        .Select(p => new
        {
            p.FirstName,
            p.LastName,
            p.Nickname,
            p.CreatedOn,
            p.CurrentWork.Title,
            p.CurrentWork.Company.CompanyName
        })
        // Forces local computation, so pulls entire people dataset :-(
        .Where(x => Regex.IsMatch(x.LastName ?? "", r)
        || Regex.IsMatch(x.FirstName ?? "", r, RegexOptions.IgnoreCase)
        || Regex.IsMatch(x.Nickname ?? "", r, RegexOptions.IgnoreCase)
        || Regex.IsMatch($"{x.FirstName} {x.LastName}", r,
                RegexOptions.IgnoreCase))
        .OrderBy(orderBy);
    }
    // Allow some wildcards in the search...
    public static String LikeToRegular(String value)
    {
        return "^" + Regex.Escape(value)
        .Replace("_", ".")
        .Replace("%", ".*") + "$";
    }
0 голосов
/ 15 октября 2018

Рассматривая запрос Linq, он выбирает только данные о людях, а не дочерние коллекции.Вы должны использовать Include для извлечения данных для дочерних коллекций вместе с родительской сущностью, как показано ниже.Подробнее о загрузке связанных сущностей здесь .

// my controller code for the function
[HttpGet]
public ActionResult<ICollection<People>> Find([FromODataUri] string text,
    [FromODataUri] string orderBy)
{
    if (text == null || text.Length == 0)
        return Get().ToList();
    if (orderBy == null || orderBy.Length == 0)
        orderBy = "CreatedOn";
    return _db.People
        .Where(p => p.FirstName.Contains(text)
            || p.LastName.Contains(text)
            || p.Nickname.Contains(text))
        .Include(p => p.CurrentWork) // I have added this line
        .OrderBy(orderBy)
        .Take(5000)
        .ToList();
}

Примечание. Вам по-прежнему необходимо использовать $ expand = CurrentWork в качестве строки запроса.Без этой строки запроса сервер удалит дочерние коллекции перед отправкой ответа клиенту.

...