Я написал раннюю версию запроса, и он частично работает и возвращает некоторые значения. Проблема в следующем:
- Я не могу выбрать направление сортировки, поскольку для этого требуется вызов OrderBy() или OrderByDescending() условно.
- для упорядочивания я не могу использовать свойства внутри дочерних объектов, так как это требует безусловного предоставления их прямо в запросе (мне нужно написать OrderBy(prop => EF.Property< object>(prop.User, sortBy))).
public async Task GetEventsPagedFilteredSorted(
int page,
int itemsPerPage,
string filterText,
string sortBy,
bool ascending,
CancellationToken cancellationToken = default)
{
var query = _db.Event
.AsNoTracking()
.Include(e => e.User)
.Where(e => e.User.UserName.Contains(filterText)
|| e.EventCode.Contains(filterText))
.OrderBy(prop => EF.Property(prop, sortBy))
.Skip(page * itemsPerPage)
.Take(itemsPerPage)
.ProjectToType()
.ToListAsync(cancellationToken)
;
return result;
}
Затем я попытался разбить запрос на более мелкие части, чтобы затем разделить его еще больше и ввести условия, но теперь по какой-то причине результат совершенно пуст.
var query = _db.Event
.AsNoTracking()
.Include(e => e.User)
.Where(e => e.User.UserName.Contains(filterText)
|| e.EventCode.Contains(filterText))
.OrderBy(prop => EF.Property(prop, sortBy))
.Skip(page * itemsPerPage)
.Take(itemsPerPage)
;
var result = await query
.ProjectToType()
.ToListAsync(cancellationToken);
return result;
Класс Event:
public class Event
{
[Key]
public int EventId { get; set; }
[Required]
[MaxLength(64)]
public string EventCode { get; set; }
public DateTime DateTime { get; set; }
[Required]
public int UserID { get; set; }
public User User { get; set; }
}
Как написать запрос со всеми необходимыми мне условиями?
ОБНОВЛЕНИЕ:
После некоторых подсказок из ответов здесь я Я остановился на этом фрагменте кода, который уже работает так, как я хотел, но все еще есть некоторое дублирование кода, от которого я хотел бы избавиться (код, предоставляющий свойства для упорядочивания):
var query = _db.Event
.AsNoTracking()
.Include(e => e.User)
;
if (!string.IsNullOrEmpty(filterText))
query = (Microsoft.EntityFrameworkCore.Query.IIncludableQueryable)
query
.Where(e => e.User.UserName.Contains(filterText) || e.EventCode.Contains(filterText))
;
IOrderedQueryable queryOrdered;
if (ascending)
queryOrdered =
query
.OrderBy(e => EF.Property(SortByContainsUser(sortBy) ? e.User : e, sortBy))
;
else
queryOrdered =
query
.OrderByDescending(e => EF.Property(SortByContainsUser(sortBy) ? e.User : e, sortBy))
;
var result = await queryOrdered.ToListAsync();
var resultAdapted = result.Select(e => e.Adapt()).ToList();
return resultAdapted;
Метод SortByContainsUser():
bool SortByContainsUser(string sortBy) => sortBy.Contains("User") || sortBy.Contains("user");
Подробнее здесь: https://stackoverflow.com/questions/791 ... -direction