如何高效地检索我的 asp .NET 应用程序中的大量数据?

问题描述 投票:0回答:1

感谢您关注我的问题 我正在尝试制作一个仪表板,显示团队中的每个重要数据(创造的销售额、损失的销售额、平均响应等)。 因此,在控制器上,我检索 mysql 数据库中的所有选定数据,以在我的视图中显示此数据,以使用 Chart.js 显示此数据。 我检索数据的代码是这样的:

        public async Task<IActionResult> Charts()
        {

            int thisMonth= DateTime.Today.Month;
            int thisYear= DateTime.Today.Year;

            var rdhTable =  _context.RequestDateHistory.Where(rdh=>rdh.Date.Year ==thisYear) ;

            var productDtos = new Dictionary<int, ProductChartsDto>();
            foreach (var rdh in rdhTable)
            {
                int productId = await FindRelatedRequestId(rdh.RequestName);
                if (productId == 0) continue;
                ProductModel product = await _context.ProductModel
                    .Include(p =>p.User)
                    .Include(p=> p.RequestModel.CountryModel)
                    .FirstAsync(p => p.ID ==productId);
                if (product != null && !productDtos.ContainsKey(productId))
                {

                    productDtos.Add(productId,new ProductChartsDto
                    {
                        ID = product.ID,
                        Type_Enum= product.Type_Enum,
                        Name = product.Name,
                        TemporaryName = product.Temporary_Name,
                        SacManager = product.User_Sac,
                        FactoryId = product.FACTORY_ID,
                        Country = product.RequestModel.CountryModel.Name

                    }) ;
                }

            }


            //var userIdToUserName = await _context.Users.ToDictionaryAsync(u => u.Id, u => u.FirstName + ' ' + u.LastName);
            var requestData =await rdhTable
                .GroupBy(rdh => rdh.Date.Month)
                .Select(group => new
                {
                    Month = group.Key,
                    CreatedRequests = group.Count(rdh => rdh.StatusID == 1),
                    LostRequests = group.Count(rdh => rdh.StatusID == 21),
                    Agreements = group.Count(rdh => rdh.StatusID == 5),
                    Delivered = group.Count(rdh => rdh.StatusID == 17),
                })
                .ToListAsync();
            Dictionary<int, string> monthLabels = new Dictionary<int, string>();

            foreach(var data in requestData)
            {
                monthLabels.Add(data.Month, CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(data.Month));
            }

            ViewBag.MonthLabels = monthLabels;
            ViewBag.CreatedRequestsDict = requestData.ToDictionary(key => key.Month, value => value.CreatedRequests);
            ViewBag.LostRequestsDict = requestData.ToDictionary(key => key.Month, value => value.LostRequests);
            ViewBag.AgreementsDict = requestData.ToDictionary(key => key.Month, value => value.Agreements);
            ViewBag.DeliveredDict = requestData.ToDictionary(key => key.Month, value => value.Delivered);




            // Get and sort Enum type counts so far this year 
             var enumTypeCounts= productDtos.Where(p=> p.Value.Type_Enum != null)
                .GroupBy(p=> p.Value.Type_Enum)
                .ToDictionary(p=> p.Key,p=> p.Count());


            // Get and sort Products count by SAC User so far this year 
            var sacWorkload = productDtos.Where(p => p.Value.SacUser != null)
                .GroupBy(p => p.Value.SacUser)
                .Select(g => new {
                    Name = g.Key.FirstName+' '+g.Key.LastName ,
                    Count = g.Count() })
                .ToDictionary(x => x.Name, x => x.Count);

            var ordersByCountry = productDtos
                .GroupBy(p => p.Value.Country)
                .ToDictionary(x => x.Key, x => x.Count());



            ViewBag.ProductTypeCounts = enumTypeCounts;
            ViewBag.SacWorkload = sacWorkload;
            ViewBag.OrdersByCountry = ordersByCountry;

            return View();


        }

顺便说一句,我的助手

FindRelatedRequestId
是查看与单个字符串相关的对象(我知道它是:

        private async Task<int> FindRelatedRequestId(string requestName)
        {
            var nameSplitted = requestName.Split('/');
            string productName = nameSplitted.Length > 1 ? nameSplitted[1] : requestName;
            var product = await _context.ProductModel
                .FirstOrDefaultAsync(p => p.Name == productName || p.Temporary_Name == productName);
            var productId = product?.ID ?? 0;
            return productId;
        }

代码按我的预期运行和检索,但对于我的情况来说,数据量太大。我的电脑可能需要 900 多秒才能检索所有内容。我知道服务器的加载时间要快得多,但仍然证明缺乏优化。

我认为这个问题首先是由于所有数据库调用造成的。不是在一条指令中调用每个对象,而是一一调用所有对象。我寻找解决方案,但没有找到任何解决方案。

我发现的第二个解决方案是创建一个缓存并将数据存储在缓存中,但我想到了一些错误:当程序每次调用此方法时看到新的和未缓存的数据时,如何使缓存不断发展和扩展?

如果您问我为什么要处理这个问题,我是一个应用程序的初级开发人员,并且在开发这个应用程序的团队中完全是我一个人,我不在编程框架中,所以我的代码没有经过另一个人(我处于一个非常特殊的情况)。 ASP .NET 版本是 2.0(我知道它太旧了)。

我目前正在尝试通过创建外键来调整数据以删除我的助手

PRODUCT_ID
,我知道这种方法并不能简化问题。

如果您有任何线索可以启发我,我会很高兴阅读它。

再次感谢您关注我的问题

mysql asp.net asp.net-core-mvc asp.net-core-2.0
1个回答
0
投票

我还猜测每次循环迭代重复调用 DB - 2 会很慢。

您可以尝试做的是一次性获取所有数据。它将需要一些代码来准备用于查询过滤的数据,然后检索特定产品,但应该更快,因为这将是一个查询。

这是示例代码:

var requestNameToProductName = rdhTable.ToDictionary(
    x => x.RequestName,
    x => 
    {
        var nameSplitted = x.RequestName.Split('/');
        return nameSplitted.Length > 1 ? nameSplitted[1] : x.RequestName;
    });
    
var productNames = requestNameToProductName.Values.ToArray();

// Fetch all data in one go.
var productModels = await _context.ProductModel
    .Where(p => productNames.Any(productName => p.Name == productName || p.Temporary_Name == productName))
    .Include(p => p.User)
    .Include(p => p.RequestModel.CountryModel)
    .ToArrayAsync();
    
foreach (var rdh in rdhTable)
{
    var productName = requestNameToProductName[rdh.RequestName];
    ProductModel product = productModels.FirstOrDefault(x => x.Name == productName || x.Temporary_Name == productName);
}
© www.soinside.com 2019 - 2024. All rights reserved.