最佳实践使用Entity Framework C#获取百万个数据SQL

我的SQL数据库中有一百万条记录,并且只有1个索引(主键)ID。 我想获取所有数据而不会使服务器崩溃,因此我使用一种批处理过程来获取整个数据。

我使用递归查询并将其存储在变量中(结果)。这需要1个小时才能获得100.000行。

这是SelectBatch的功能:

public List<TDto> SelectBatch<TEntity, TDto>(
    IRepository<TEntity, TDto> repository,
    int totalCurrentData, 
    Expression<Func<TEntity, DateTime>> orderBy,
    Expression<Func<TEntity, bool>> condition,
    Expression<Func<TEntity, TDto>> convertToDto,
    List<TDto> results = null,
    int page = 1,
    int pageSize = 1000)
{
    if(results == null)
    {
        results = new List<TDto>();
    }
    int totalPage = (int)Math.Ceiling((double)totalCurrentData / pageSize);

    _logger.LogDebug($"Start SelectBatch, page: {page} pageSize:{pageSize} totalPage:{totalPage} totalCurrentData:{totalCurrentData} ");

    totalCurrentData -= pageSize;
    int pageSkip = Math.Max(0, (page - 1)) * pageSize;

    List<TDto> currentData = repository.MakeQuery().OrderBy(orderBy).Where(condition)
        .Skip(pageSkip)
        .Take(pageSize)
        .Select(convertToDto)
        .ToList();
    if(currentData != null && currentData.Count > 0)
    {
        results.AddRange(currentData);
    }

    if (totalCurrentData > 0)
    {
        page++;
        return SelectBatch(repository, totalCurrentData, orderBy, condition, convertToDto, results,page,pageSize);
    }
    _logger.LogDebug($"Finish SelectBatch, Page: {page} Page Size:{pageSize} Total Current Data : {results.Count} ");

    return results;

}

插入或更新数据

  List<DD> list; // DATA FROM THIRD PARTY 
  List<DD> currentList = SelectBatch(_REPO, totalCurrentData,
                x => x.CreatedDate, 
                x => DateTime.Parse(x.ReportDate) >= dates.Min() && DateTime.Parse(x.ReportDate) <= dates.Max(),
                x => new DD(x)).ToList();

  List<DD> newData = new List<DD>();
            List<DD> oldData = new List<DD>();

            foreach (var item in list)
            {
                if (currentList.Any(curr =>
                curr.ReportDate == item.ReportDate &&
                curr.UserName== item.UserName&&
                 (curr.FileSharedExternally != item.FileSharedExternally ||
                 curr.FilesSynced != item.FilesSynced ||
                 curr.LastActivityDate != item.LastActivityDate)))
                {
                    oldData.Add(item);
                }
                else if (!currentList.Any(curr =>
                    curr.ReportDate == item.ReportDate &&
                    curr.UserName == item.UserName))
                {
                    newData.Add(item);
                }
            }
还有其他更好的方法吗?我需要将所有数据存储在一个变量中,以便可以与其他数据进行比较。
评论