我有两个实体之间的一对多关系,需要查询这两个实体的组合。
一个是File模型:
public class FileMetadata
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string UserName { get; set; }
public DateTime UploadDate { get; set; }
public int FileContentId { get; set; }
public FileContent Content { get; set; }
public int UserId { get; set; }
public User User { get; set; }
}
字符串
另一个是Tag模型:
public class FileTag
{
[Key]
public int Id { get; set; }
public string Text { get; set; }
public int FileMetadataId { get; set; }
public FileMetadata Metadata { get; set; }
}
型
这种关系的本质是,一个文件可以有一对多的标签。我需要做的是实现一个搜索方法,可以搜索文件的内容(描述,名称等),但 * 也 *,搜索该文件的所有标签。这就是问题所在,我找不到一个 * 有效 * 的方法来做到这一点。
这就是我到目前为止所做的,它给了我预期的结果,但是,它不是有效的:
public async Task<ServiceResponse<FileSearchResult>> SearchFileMetaData(string searchText, int page, float resultsPerPage)
{
var pageCount = Math.Ceiling((await FindFilesBySearchText(searchText)).Count / resultsPerPage);
//Add tags to descriptions
var extendedFiles = _context.Files.ToList();
var tags = _context.FileTags.ToList();
foreach (var file in extendedFiles)
{
var thisFilesTags = tags.Where(t => t.FileMetadataId == file.Id).ToList();
foreach (var tag in thisFilesTags)
{
file.Description += tag.Text;
}
}
//Search files with metadata matching the search text.
var files = extendedFiles
.Where(f => f.Name.ToLower().Contains(searchText.ToLower())
|| f.Description.ToLower().Contains(searchText.ToLower()))
.Skip((page - 1) * (int)resultsPerPage)
.Take((int)resultsPerPage)
.ToList();
var response = new ServiceResponse<FileSearchResult>
{
Data = new FileSearchResult
{
Files = files,
ThisPageNumber = page,
TotalPages = (int)Math.Floor(pageCount)
}
};
return response;
}
型
我从数据库中获取 * 所有 * 文件和标记,循环使用File实体的标记构建描述字段,然后执行Linq操作过滤搜索文本。
我如何才能仍然得到预期的结果,但提高性能,而不是得到不必要的记录?
另外,这个问题是否可以用一个更好的Linq查询来解决,它可以连接这两个实体?或者,关系/表是否需要重新定义?
1条答案
按热度按时间oaxa6hgo1#
尝试以下查询。它试图在物化之前过滤掉文件。为了确定这不是理想的解决方案,
Contains
执行全表扫描,如果表太大,可能会影响性能。字符串