感谢您关注我的问题 我正在尝试制作一个仪表板,显示团队中的每个重要数据(创造的销售额、损失的销售额、平均响应等)。 因此,在控制器上,我检索 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
,我知道这种方法并不能简化问题。
如果您有任何线索可以启发我,我会很高兴阅读它。
再次感谢您关注我的问题
我还猜测每次循环迭代重复调用 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);
}