我的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();
    }

我的Asp.Net MVC页面需要12秒.加载

你做错了很多事情,或者至少做得很糟糕。首先,您将返回来自各种查询的所有记录,并在内存中处理它们。如果只有几个记录就可以了,但是你说有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分钟。