Entity Framework Core возвращает все данные, если значение фильтра равно нулю - PullRequest
0 голосов
/ 18 июня 2019

Я хотел бы знать, возможно ли в предложении where просто вернуть все данные, когда отфильтрованное значение равно нулю.

У меня есть ViewModel с параметрами поиска, если они нулевые, я просто хочу всепричина в том, что данные должны быть возвращены, причина состоит в том, чтобы избежать повторения кода, используя предложения if, которые выглядят грязными из-за нулевой проверки.

Вот мой метод

public void OnPost()
{
    if (POEViewModel.ReferenciaId != null)
    {
        POE = _context.Componentes
               .Include(c => c.Registo)
               .ThenInclude(r => r.Celula)
               .Where(c =>
                 c.Registo.ReferenciaId == POEViewModel.ReferenciaId &&
                 c.Registo.DataInicioTurno >= POEViewModel.DataInicio && c.Registo.DataInicioTurno <= POEViewModel.DataFim)
               .OrderByDescending(c => c.Id)
               .ToList();
    }
    else if (POEViewModel.Operador != null)
    {
        POE = _context.Componentes
               .Include(c => c.Registo)
               .ThenInclude(r => r.Celula)
               .Where(c =>
                 c.Registo.DataInicioTurno >= POEViewModel.DataInicio && c.Registo.DataInicioTurno <= POEViewModel.DataFim &&
                 c.Registo.Operador == POEViewModel.Operador)
               .OrderByDescending(c => c.Id)
               .ToList();
    }
    else if (POEViewModel.ReferenciaId != null && POEViewModel.Operador != null)
    {
        POE = _context.Componentes
               .Include(c => c.Registo)
               .ThenInclude(r => r.Celula)
               .Where(c =>
                 c.Registo.ReferenciaId == POEViewModel.ReferenciaId &&
                 c.Registo.DataInicioTurno >= POEViewModel.DataInicio && c.Registo.DataInicioTurno <= POEViewModel.DataFim &&
                 c.Registo.Operador == POEViewModel.Operador)
               .OrderByDescending(c => c.Id)
               .ToList();
    }
    else
    {
        POE = _context.Componentes
              .Include(c => c.Registo)
              .ThenInclude(r => r.Celula)
              .Where(c =>
                c.Registo.DataInicioTurno >= POEViewModel.DataInicio && c.Registo.DataInicioTurno <= POEViewModel.DataFim)
              .OrderByDescending(c => c.Id)
              .ToList();
    }

    ViewData["ReferenciaId"] = new SelectList(_context.Referencias, "Id", "Nome");
}

Это может быть немного сложно для внешних ключей, потому что они принимают только целые числа, чтобы найти общее решение.

Ответы [ 3 ]

1 голос
/ 18 июня 2019

Затем вы можете смешать проверку null с оператором ||, как это

POE = _context.Componentes
               .Include(c => c.Registo)
               .ThenInclude(r => r.Celula)
               .Where(c =>
                 (POEViewModel.ReferenciaId==null || 
                  c.Registo.ReferenciaId == POEViewModel.ReferenciaId) &&
                 (POEViewModel.DataInicio==null||c.Registo.DataInicioTurno >= POEViewModel.DataInicio)
                 && 
                (POEViewModel.DataFim==null||c.Registo.DataInicioTurno <= POEViewModel.DataFim))
               .OrderByDescending(c => c.Id)
               .ToList();

Существует свойство .HasValue, которое возвращает логическое значение и может помочь вам проверить, есть ли у вашего параметра значение или нет. это относится только к обнуляемым типам. Таким образом, вместо POEViewModel.DataInicio==null вы можете написать POEViewModel.DataInicio.HasValue

1 голос
/ 18 июня 2019

Вы можете заранее построить свой предикат:

public void OnPost()
{
    Expression<Func<Component, bool>> filter = c => 
        (POEViewModel.ReferenciaId != null ? c.Registo.ReferenciaId == POEViewModel.ReferenciaId : true) &&
        (POEViewModel.Operador != null ? c.Registo.Operador == POEViewModel.Operador : true);   

    POE = _context.Componentes
          .Include(c => c.Registo)
          .ThenInclude(r => r.Celula)
          .Where(filter)
          .Where(c =>
            c.Registo.DataInicioTurno >= POEViewModel.DataInicio && c.Registo.DataInicioTurno <= POEViewModel.DataFim)
          .OrderByDescending(c => c.Id)
          .ToList();

    ViewData["ReferenciaId"] = new SelectList(_context.Referencias, "Id", "Nome");
} 
0 голосов
/ 18 июня 2019

Сделать null check внутри Where:

POE = _context.Componentes
    .Include(c => c.Registo).ThenInclude(r => r.Celula)
    .Where(c =>
        // Check for null before equality
        (POEViewModel.ReferenciaId == null || c.Registo.ReferenciaId == POEViewModel.ReferenciaId) &&
        // Check for null before equality
        (POEViewModel.Operador == null || c.Registo.Operador == POEViewModel.Operador) &&
        c.Registo.DataInicioTurno >= POEViewModel.DataInicio && 
        c.Registo.DataInicioTurno <= POEViewModel.DataFim)
    .OrderByDescending(c => c.Id)
    .ToList();
...