Есть ли способ фильтровать на основе свойства в EF?
public async Task<Challenge?> GetByIdAsync(int id)
{
var item = await _context.Challenges
.Include(x => x.Upload) // Where Upload.DeletedOn == null Else null
.FirstOrDefaultAsync(x => x.Id == id && x.DeletedOn == null);
return item;
}
Я знаю, что могу потом фильтровать, но я не хочу этого делать и усложнять, поскольку будет более 100 API, которым потребуется несколько похожий фильтр.
Пытался пройти через это, но это не в отношении один-к-одному - фильтруется-включается
Да, именно если DeletedOn НЕ NULL, не загружайте его. В моем приложении => DeletedOn == null означает НЕ удаленный, а DeletedOn != null означает удаление в эту дату (мягкое удаление)
Фильтрованное включение предназначено не только для отношений «один к одному». Но да, его нельзя использовать для отношений x-1.
Вы можете сделать это двумя способами:
Использование Глобальных фильтров запросов:
Определите фильтр для обоих объектов следующим образом:
modelBuilder.Entity<Challenge>().HasQueryFilter(x => x.DeletedOn == null);
modelBuilder.Entity<Upload>().HasQueryFilter(x => x.DeletedOn == null);
Если ваши сущности реализуют интерфейс или наследуют от базового класса, вы можете применить фильтр запроса ко всем из них, используя простой метод расширения, например этот: ApplyQueryFilter.
modelBuilder.ApplyQueryFilter<ISoftDelete>(e => e.DeletedOn == null);
Тогда ваш запрос будет простым:
public async Task<Challenge?> GetByIdAsync(int id)
{
var item = await _context.Challenges
.Include(x => x.Upload)
.FirstOrDefaultAsync(x => x.Id == id);
return item;
}
Используя Select
:
public async Task<Challenge?> GetByIdAsync(int id)
{
var item = await _context.Challenges
.Where(x => x.Id == id && x.DeletedOn == null)
.Select(x => new Challenge
{
Id = x.Id,
// other properties
Upload = x.Upload.DeletedOn == null ? x.Upload : null
})
.FirstOrDefaultAsync();
return item;
}
Вы не хотите загружать свойство
Upload
, если оно удалено? Я прав?