搜索方法连接多个表

时间:2016-12-10 21:31:21

标签: c# linq search entity-framework-core

我需要一个搜索方法的帮助来搜索表格中的匹配文本。 这是有效的,除了连接需要LEFT OUTER JOIN,否则如果在任何表中缺少pageId,我都不会得到任何结果。

此解决方案需要很长时间才能运行,如果有人可以帮助我找到更好的解决方案来处理此任务,我将不胜感激。

public async Task<IEnumerable<Result>> Search(string query)
    {

        var temp = await (from page in _context.Pages
                          join pageLocation in _context.PageLocations on page.Id equals pageLocation.PageId
                          join location in _context.Locations on pageLocation.LocationId equals location.Id
                          join pageSpecialty in _context.PageSpecialties on page.Id equals pageSpecialty.PageId
                          join specialty in _context.Specialties on pageSpecialty.SpecialtyId equals specialty.Id

                          where
                              page.Name.ToLower().Contains(query)
                              || location.Name.ToLower().Contains(query)
                              || specialty.Name.ToLower().Contains(query)
                          select new Result
                          {
                              PageId = page.Id,
                              Name = page.Name,
                              Presentation = page.Presentation,
                              Rating = page.Rating
                          }).ToListAsync();

        var results = new List<Result>();

        foreach (var t in temp)
        {
            if (!results.Exists(p => p.PageId == t.PageId))
            {
                t.Locations = GetLocations(t.PageId);
                t.Specialties = GetSpecialties(t.PageId);
                results.Add(t);
            }
        }

        return results;
    }

1 个答案:

答案 0 :(得分:0)

使用导航属性,查询可能如下所示:

var temp = await (from page in _context.Pages
                  where Name.Contains(query)
                     || page.PageLocation.Any(pl => pl.Location.Name.Contains(query))
                     || page.PageSpecialties.Any(pl => pl.Specialty.Name.Contains(query))
                 select new Result
                  {
                      PageId = page.Id,
                      Name = page.Name,
                      Presentation = page.Presentation,
                      Rating = page.Rating,
                      Locations = page.PageLocation.Select(pl => pl.Location),
                      Specialties = page.PageSpecialties.Select(pl => pl.Specialty)
                  }).ToListAsync();

这有几个好处:

  1. 如果没有联接,查询会立即返回唯一的Result个对象,因此您不需要在之后对其进行重复删除。
  2. 位置和专长在同一个查询中加载,而不是每个Result(又名 n + 1个问题)的两个查询。
  3. (可能)ToLower已删除,因为无论如何搜索可能不区分大小写。查询以SQL身份执行,大多数情况下,SQL数据库具有不区分大小写的排序规则。删除ToLower会再次进行查询sargable