Following code works for a single .Contains(tag)
public async Task<List<CreateVideoWithTagNamesDTO>> FindVideosByTag(Tag tag)
{
var result = await _db.Where(p => p.Tags.Contains(tag))
.Select( item => new CreateVideoWithTagNamesDTO
{
Description = item.Description,
Title = item.Title,
Url = item.Url,
Tags = _mapper.Map<IList<CreateTagDTO>>(item.Tags)
}).ToListAsync();
return result;
}
How would I query Tags.Contains for multiple Tags ? Lets say this function will take in array of Tags, Tag[] tags How do I include .Contains to include all tags? So it would select videos which have each tag present ?
CodePudding user response:
For multiple tags you need to combine Any
and Contains
methods like below :
public async Task<List<CreateVideoWithTagNamesDTO>> FindVideosByTag(ICollection<Tag> tags)
{
var result = await _db.Where(p => p.Tags.Any(tag=> tags.Contains(tag)))
.Select( item => new CreateVideoWithTagNamesDTO
{
Description = item.Description,
Title = item.Title,
Url = item.Url,
Tags = _mapper.Map<IList<CreateTagDTO>>(item.Tags)
})
.ToListAsync();
return result;
}
As @Panagiotis Kanavos pointed this may not work for complex objects EF will fail to convert this into SQL query but you can always fall back to this :
public async Task<List<CreateVideoWithTagNamesDTO>> FindVideosByTag(ICollection<Tag> tags)
{
var tagIds = tags.Select(r=> r.Id).ToArray();
var result = await _db.Where(p => p.Tags.Select(r=> r.Id).Any(tag=> tagIds.Contains(tag)))
.Select( item => new CreateVideoWithTagNamesDTO
{
Description = item.Description,
Title = item.Title,
Url = item.Url,
Tags = _mapper.Map<IList<CreateTagDTO>>(item.Tags)
})
.ToListAsync();
return result;
}
CodePudding user response:
You can use Intersect function in list to get matched items and use that u can refer to below question Check if one IEnumerable contains all elements of another IEnumerable
CodePudding user response:
You could also do something along the lines of
public async Task<List<CreateVideoWithTagNamesDTO>> FindVideosByTag(List<Tag> inputTags)
{
var result = await _db.Where(p => p.Tags.ToList().Intersect(inputTags).Any()) {
Description = item.Description,
Title = item.Title,
Url = item.Url,
Tags = _mapper.Map<IList<CreateTagDTO>>(item.Tags)
})
.ToListAsync();
return result;
}