首页 > 解决方案 > 在 Entity Framework Core 中查询必须包含一组值的记录

问题描述

我正在尝试在站点中创建一个过滤系统,该系统可以用多个标签标记的一组记录。最终我希望过滤器支持 OR、AND 和 NOT,但现在我只是想让 AND 工作。

以下是具有相关属性的实体,它们只是在 EF Core 中建模的多对多关系。

public class Record
{
     public int Id { get; set; }
     public ICollection<RecordTag> RecordTags { get; set; }
}

public class RecordTag
{
    public int RecordId { get; set; }
    public Song Record { get; set; }

    public int TagId { get; set; }
    public Tag Tag { get; set; }
}

public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<RecordTag> RecordTags { get; set; }
}

我尝试编写一个 EF Core 查询,如下所示:

var tagList = tags.Split(',');
// tagList now contains the strings of tags the user has filtered on

Records = recordRepository.Query() // simply returns IQueryable<Records> 
          .Where(r=> tagList.All(  // For each record, iterate through all tags selected by the user
                t => r.RecordTags.Select(rt => rt.Tag.Name).Contains(t))) // For each user selected tag, get all the tags on the record and ensure it contains the tag we're iterating over
                .Include(r => r.RecordTags).ThenInclude(rt => rt.Tag).ToList(); // Include the tag data back with the parent entity.

但是,这会引发错误

[查询] 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估

我宁愿不必带回更大的集合并在应用程序服务器上对其进行过滤,而是直接针对数据库正确构建查询。

为什么这个查询无效?还有另一种写法吗?

标签: entity-framework-core

解决方案


您可以在 foreach 循环中添加 where 条件。

var recordRepositoryQuery = recordRepository.Query();
foreach(var tag in taglist)
{       
   recordRepositoryQuery = recordRepositoryQuery.Where(r => r.RecordTags.Select(rt => rt.Tag.Name).Contains(tag))
}

推荐阅读