我的Asp.Net MVC页面需要12秒.加载
本文关键字:12秒 加载 Asp Net MVC 我的 | 更新日期: 2023-09-27 18:10:24
我有一个这样的MVC控制器
public ActionResult Index(int vendor=-1, int product = -1, string error="", string mode="Shortfall")
{
if (Session["UserId"] == null)
return RedirectToAction("Index", "Login");
var products = DbContext.GetAllProducts();
List<SurplusViewModel> surplusList = new List<SurplusViewModel>();
Dictionary<int, string> searchVendor = new Dictionary<int, string>();
Dictionary<int, string> searchProds = new Dictionary<int, string>();
if (products.Count() > 0)
{
foreach (var prod in products)
{
SurplusViewModel s = new SurplusViewModel(prod);
surplusList.Add(s);
foreach (var v in s.Vendors)
{
if (!searchVendor.ContainsKey(v.CorpId))
{
searchVendor.Add(v.CorpId, v.CorpName);
}
}
if(!searchProds.ContainsKey(s.ProductId))
searchProds.Add(s.ProductId, s.ProductVM.ProductCode + " / " + s.ProductVM.ProductPartNo);
}
}
ViewData["vendorList"] = searchVendor;
ViewData["productList"] = searchProds;
ViewData["selectVendor"] = vendor;
ViewData["selectProd"] = product;
ViewData["mode"] = mode;
ViewBag.Message = "";
ViewBag.Error = "";
IEnumerable<SurplusViewModel> finalList = surplusList.OrderBy(o => o.Difference).ToList();
if (vendor > 0)
{
Corporation searchcorp = DbContext.GetCorporation(vendor);
finalList = finalList.Where(x => x.VendorNames.IndexOf(searchcorp.CorpName) >= 0);
}
if (product > 0)
{
finalList = finalList.Where(x => x.ProductId == product);
}
if (vendor < 0 && product < 0)
{
if (mode.Equals("Shortfall"))
finalList = finalList.Where(f => f.VendorQuantity - (f.CMQuantity + f.OEMQuantity) < 0);
else if (mode.Equals("Surplus"))
finalList = finalList.Where(f => f.VendorQuantity - (f.CMQuantity + f.OEMQuantity) > 0);
}
return View(finalList);
//return View();
}
在本地主机上加载大约需要20秒。我能做些什么来改善我的应用程序的加载时间?如果在本地主机上需要20秒,我认为它在互联网上将非常慢。有什么建议吗?
编辑:SurplusViewModel代码public SurplusViewModel(Product product)
{
int productId = product.ProductId;
ProductId = productId;
ProductVM = new ProductViewModel(product);
var saleDetsCM = from s in DbContext.GetSalesOrderDetailsFromCM()
where s.ProductId == productId && s.SaleStatus.Equals("Open") && (s.OrderType.ToLower().Equals("prototype") || s.OrderType.ToLower().Equals("production"))
orderby s.SalDetId descending
select s;
var saleDetsOEM = from s in DbContext.GetSalesOrderDetailsFromOEMs()
where s.ProductId == productId && s.SaleStatus.Equals("Open") && (s.OrderType.ToLower().Equals("prototype") || s.OrderType.ToLower().Equals("production"))
orderby s.SalDetId descending
select s;
var shipQty = from s in DbContext.GetAllSalesDets()
where s.ProductId == productId && !s.SaleStatus.Equals("Open") && (s.OrderType.ToLower().Equals("prototype") || s.OrderType.ToLower().Equals("production"))
orderby s.SalDetId descending
select s;
CustomerOrdersFromCMs = saleDetsCM.ToList();
CustomerOrdersFromOEMs = saleDetsOEM.ToList();
VendorOrders = (from p in DbContext.GetPurchaseDetsForProduct(productId)
where p.OrderType != null && (p.OrderType.ToLower().Equals("prototype") || p.OrderType.ToLower().Equals("production"))
select p).ToList();
var poIds = from v in VendorOrders
select v.PodPOId;
BatchPurchaseDetails = DbContext.GetBatchPurchaseForProduct(productId).ToList();
VendorOrderCount = 0;
VendorQuantity = 0;
var purchaseOrds = (from po in DbContext.GetPurchaseOrdersForProduct(productId)
where poIds.Contains(po.POId)
select po).ToList();
List<int> vendIds = new List<int>();
foreach (var po in purchaseOrds)
{
vendIds.Add(po.VendorId.Value);
}
var vendors = from v in DbContext.GetAllCorps()
where vendIds.Contains(v.CorpId)
select v;
foreach (var podet in VendorOrders)
{
double totalbatchqty = 0;
var purdetBatch = DbContext.GetBatchDetailsForPurchaseDet(podet.PodId);
VendorQuantity += podet.Quantity;
foreach (var b in purdetBatch)
{
totalbatchqty += b.Quantity;
VendorQuantity -= b.Quantity;
}
if (totalbatchqty >= podet.Quantity)
{
}
else
{
VendorOrderCount++;
}
}
Vendors = vendors.ToList();
VendorNames = "";
foreach (var vnd in Vendors)
{
VendorNames += vnd.CorpName + ",";
}
if (VendorNames.Length > 0)
{
VendorNames = VendorNames.Substring(0, VendorNames.Length - 1);
}
OEMQuantity = 0;
foreach (var item in CustomerOrdersFromOEMs)
{
OEMQuantity += item.Quantity;
}
CMQuantity = 0;
foreach (var item in CustomerOrdersFromCMs)
{
CMQuantity += item.Quantity;
}
ShipQuantity = 0;
foreach (var item in shipQty)
{
ShipQuantity += item.Quantity;
}
Difference = VendorQuantity - (CMQuantity + OEMQuantity);
//TotalInsideSalesOrder = VendorOrders.Count();
}
你做错了很多事情,或者至少做得很糟糕。首先,您将返回来自各种查询的所有记录,并在内存中处理它们。如果只有几个记录就可以了,但是你说有50个产品。有多少供应商?有多少公司?
你正在做几个数据库查询,听起来你在实例化的子对象中做了更多的查询。所有这些查询都需要时间。这就是为什么您希望通过编写更具包容性的单个查询来最小化查询,并在单个(或尽可能少的)查询中在sql server上执行尽可能多的工作。
你可以优化的区域…不要使用Count() > 0
,而是使用.Any()
. any在找到第一个记录后返回true,而不是必须计数所有内容,然后将该数字与0进行比较。
另一个区域,你在foreach中执行foreach。这将创建n * m个循环。例如,如果有两个产品和两个供应商,那就是4个循环,但如果每个有3个,那就是9个循环,如果每个有4个,那就是16个循环。如果是2500个循环中的50个。每一个循环执行你的SurplusViewModel构造函数,如果它有很多代码,这意味着它会很慢。
我从你的更新中看到,SurplusViewModel执行至少7个查询,也许更多。这很难说。因此,这是2500 * 7或17,500个查询(假设50个产品和50个供应商)。你开始明白为什么它这么慢了吗?现在,假设你有100种产品和100个供应商。这是1万个循环,有7个以上的查询,至少有7万个查询。这不是可扩展的解决方案。
让我们进一步看……在所有这些"Getxxx"方法中有什么?我想每个都有一些查询?您是否可能每次都执行双重查询?同样,你没有包括所有的信息。
老实说,我很惊讶这只花了20秒…我认为不管数据量是多少,它应该更像是20分钟。