-1

我正在寻求有关构建搜索栏的帮助。我在这里有 3 个数据库表:Case-> Exhibit-> TaskingCaseExhibit的父母并且ExhibitTasking的父母。我有一个表格,其中显示了Taskings他们的父母 ID ( Exhibit) 和祖父母 ID ( Case) 的列表中的信息。

我希望能够Taskings根据CaseID 进行搜索。这是我当前的解决方案(作品),显示和搜索速度很慢,有 2000 个任务。

我认为这是因为循环中有 2 个 find 语句。这IsMatchedTasking也是一个复杂的查询,我无法仅使用 linq 语句编写。

理想的情况是将一个查询存储为IQueryable保留所有父关系的查询,并将其传递到搜索中。但由于我使用PagedList的是,当它传递到视图中时,它将摆脱父关系。

关于如何正确执行此操作而无需查看 db 上下文 3 次的任何建议(在 db 中查询Taskings、在 db 中过滤搜索并检查 db 以显示父属性)?

public ActionResult GetNew(int? page, int? pageSize, string searchString)
{
    int pageNumber = page ?? 1;
    var currUser = _userManager.FindByNameAsync(User.Identity.Name).Result;
    var ps = Util.SetSessionPageSize(10, pageSize, HttpContext, "taskingGetNewPageSize");
    var output = new List<TaskingViewModel>();
    foreach (var tsk in _dbContext.Taskings) {
        if (currUser.IsMatchedTasking(tsk, _dbContext)) {
            var ex = _dbContext.Exhibits.Find(tsk.ExhibitId);
            var ca = _dbContext.Cases.Find(ex.ParentCaseId);
            output.Add(new TaskingViewModel
            {
                Tasking = tsk,
                ExhibitId = ex.Id,
                ExhibitName = ex.GetExhibitName(),
                CaseId = ca.Id,
                CasePriority = ca.GetCasePosition(_dbContext.TopTens.ToSortedList(_dbContext)),
            });
        }
    }
    var result = Search(searchString, output);
    return View(result.ToPagedList(pageNumber, pageSize: ps));
}

搜索函数返回一个新ListTaskingViewModel匹配 caseIds 与searchStringusing 包含。

public List<TaskingViewModel> Search(string searchString, List<TaskingViewModel> toSearch)
{
    var result = new List<TaskingViewModel>();
    if (String.IsNullOrEmpty(searchString))
        return toSearch;
    foreach(var item in toSearch) {
        if (item.Id.Contains(searchString))
            result.Add(item);
    }
    return result;
}
4

1 回答 1

1

在不了解您的问题的更多细节的情况下,很难得出一个明确的答案,但这里有一些改进方法:

  1. 尝试将其设为可以转换为 Sql 的单个查询。如果IsMatchedTasking是可以转换为 sql 的条件,并且您的实体之间存在导航属性,则这是可能的。所以查询将类似于:
var output = _dbContext.Taskings.Whete(x => x.UserId == userId)
.Select(x => new TaskingViewModel
            {
                TaskId = x.Id,
                TaskName = x.Name,
                ExhibitId = x.ExhibitionId,
                ExhibitName = ex.Exhibition.Name,
                CaseId = x.CaseId,
                CasePriority = x.Case.Priority,
            }.ToList()

但具体取决于您的业务逻辑。

  1. 如果 #1 很难、不可能或违背您的架构理念,那么首先质疑您的架构理念,但您仍然可以通过以下方式让事情变得稍微好一点:_dbContext.Exhibits.ToList()并且_dbContext.Cases.ToList()在开始循环之前。这样,所有Cases 和所有Exhibits 都将被 db 上下文跟踪,并且 Find() 内部循环不会导致数据库往返。但是,这可能是不可扩展的,因为实例的数量可能太高了。
于 2020-11-19T08:17:44.317 回答