linq 有什么方法可以提高EF Core的性能?

7z5jn7bk  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(179)
List<tablename> results = new List<tablename>();

if (viewModel.CSku != null )
{
    results = _context.tablename
                      .Where(x => x.CSku == viewModel.CSku)
                      .AsNoTracking().ToList();

    if (viewModel.CDesc != null)
        results = results.Where(x => x.CDesc.Contains(viewModel.CDesc.ToUpper())).ToList();

    if (viewModel.WCode != null)
        results = results.Where(x => x.WCode.Contains(viewModel.WCode.ToUpper())).ToList();

    return _mapper.Map<IEnumerable<tablenameViewModel>>(results).ToList();
}

if (viewModel.Length == null && viewModel.Pattern == null && 
    viewModel.Length == null && viewModel.Prefix == null && 
    viewModel.Species == null)
{
    var x = _context.tablename.AsNoTracking().ToList();

    if (viewModel.WCode != null)
        x = x.Where(x => x.WCode.Contains(viewModel.WCode.ToUpper())).ToList();
        return _mapper.Map<IEnumerable<tablenameViewModel>>(x) ;
}
else
{
    results = _context.tablename.AsNoTracking().ToList();

    if (viewModel.Length != null)
        results = results.Where(x => x.Length.Trim() == viewModel.Length.Trim()).ToList();

    if (viewModel.Species != null)
        results = results.Where(x => x.Species.Trim() == viewModel.Species.Trim()).ToList();

    if (viewModel.Pattern != null)
        results = results.Where(x => x.Pattern.Trim() == viewModel.Pattern.Trim()).ToList();

    if (viewModel.Prefix != null)
        results = results.Where(x => x.Prefix.Trim() == viewModel.Prefix.Trim()).ToList();

    if (viewModel.WCode != null)
        results = results.Where(x => x.WCode.Contains(viewModel.WCode.ToUpper())).ToList();

    return _mapper.Map<IEnumerable<tablenameViewModel>>(results);
}

上面的代码即使在过滤条件下也需要2分钟才能加载。我尝试了.AsNoTracking(),但它仍然需要同样的时间来加载。
有什么方法可以修改代码并提高页面的性能吗?

hyrbngr7

hyrbngr71#

您需要动态地构建查询。results = _context.tablename.AsNoTracking().ToList();将从表中提取所有行到内存中,由于显而易见的原因,这可能非常慢。对于初学者,您可以执行以下操作:

if (viewModel.CSku != null )
{
    var query = _context.tablename
         .Where(x => x.CSku == viewModel.CSku)
         .AsNoTracking();

    if (viewModel.CDesc != null)
        query = query.Where(x => x.CDesc.Contains(viewModel.CDesc.ToUpper()));

    if (viewModel.WCode != null)
        query = query.Where(x => x.WCode.Contains(viewModel.WCode.ToUpper()));

    return _mapper.Map<IEnumerable<tablenameViewModel>>(query.AsEnumerable()).ToList();
}

然后将类似的方法用于其他情况。
请注意,AutoMapper有queryable extensions,在某些情况下可以使用ProjectTo(并非所有Map都可以转换为SQL),即:

return query
    .ProjectTo<tablenameViewModel>(_mapper.ConfigurationProvider)
    .ToList();

这具有仅查询所需列的优点。

相关问题