Linq Query执行这么长时间

时间:2016-01-17 03:42:16

标签: c# .net linq linq-to-sql

这是我的linq查询,这需要很长时间才能执行。任何人都可以建议我如何让它更快。我正在使用此查询中的一些函数来动态计算数据。当我删除这些功能时,这个查询运行得很快,但我必须使用这些功能以正确的方式获取数据。请有人建议我如何改进此查询

  var l = from a in GetItemList(con)
                        join product in GetProductStock(con) on
                            a.Id
                            equals product.Id
                            into prodList
                        from prod in prodList.DefaultIfEmpty()
                        join brand in GetBrandStock(con) on
                            a.PbPairId equals brand.Id
                            into brandList
                        from bran in brandList.DefaultIfEmpty()
                        join pack in GetPackStock(con) on
                            a.PbpPairId equals pack.Id
                            into packList
                        from pac in packList.DefaultIfEmpty()
                        join np in RtbVoucherVoPurSalItem.GetTotalBuySellByItemForNormal(con) on a.Id equals np.ItemId
                            into npl
                        from npv in npl.DefaultIfEmpty()
                        join pp in RtbVoucherVoPurSalItem.GetTotalBuySellByItemForNormal(con) on a.Id equals pp.ItemId
                            into ppl
                        from ppv in ppl.DefaultIfEmpty()
                        select
                            new RsXtraProductListWithClosing
                                {
                                    Id = a.Id,
                                    PbPairId = a.PbPairId,
                                    PbpPairId = a.PbpPairId,
                                    ProductId = a.ProductId,
                                    BrandId = a.BrandId,
                                    PackId = a.PackId,
                                    DesignNoId = a.DesignNoId,
                                    Product = a.Product.Trim(),
                                    Brand = a.Brand.Trim(),
                                    Pack = a.Pack.Trim(),
                                    DesignNo = a.DesignNo.Trim(),
                                    QuantityUnitId = a.QuantityUnitId,
                                    RateUnitId = a.RateUnitId,
                                    AskDesignNo = a.AskDesignNo,
                                    AskCustomSize = a.AskCustomSize,
                                    AskDesignNoRate = a.AskDesignNoRate,
                                    UseBachNumber = a.UseBachNumber,
                                    UseExpDate = a.UseExpDate,
                                    UseManfacDate = a.UseManfacDate,
                                    AskD = a.AskD,
                                    AskH = a.AskH,
                                    AskW = a.AskW,
                                    SaD = a.SaD,
                                    SaH = a.SaH,
                                    SaW = a.SaW,
                                    SaleByPump = a.SaleByPump,
                                    ScalGroup = a.ScalGroup,
                                    CalculationUnitId = a.CalculationUnitId,
                                    UnitSize = a.UnitSize,
                                    LowStockQuantity = a.LowStockQuantity,
                                    OverStockQuantity = a.OverStockQuantity,
                                    SizeAs = a.SizeAs,
                                    UseDirectDiscount = a.UseDirectDiscount,
                                    Discount = a.Discount,
                                    PurchaseRate1 = a.PurchaseRate1,
                                    PurchaseRate2 = a.PurchaseRate2,
                                    PurchaseRate3 = a.PurchaseRate3,
                                    PurchaseOtherRate = a.PurchaseOtherRate,
                                    SaleRate1 = a.SaleRate1,
                                    SaleRate2 = a.SaleRate2,
                                    SaleRate3 = a.SaleRate3,
                                    SaleOtherRate = a.SaleOtherRate,
                                    LockOtherPurchaseRate = a.LockOtherPurchaseRate,
                                    LockOtherSaleRate = a.LockOtherSaleRate,
                                    LockSaleRate = a.LockSaleRate,
                                    LockPurchaseRate = a.LockPurchaseRate,
                                    ProductClosingStock = ((a.Pobu ?? prod.OpeningStock ?? 0) + (npv.Quantaty ?? 0)),
                                    ProductCClosingStock = ((a.CPobu ?? prod.COpeningStock ?? 0) + (ppv.Quantaty ?? 0)),
                                    BrandClosingStock = ((a.Bobu ?? bran.OpeningStock ?? 0) + (npv.Quantaty ?? 0)),
                                    BrandCClosingStock = ((a.CBobu ?? bran.COpeningStock ?? 0) + (ppv.Quantaty ?? 0)),
                                    PackClosingStock = ((a.Paobu ?? pac.OpeningStock ?? 0) + (npv.Quantaty ?? 0)),
                                    PackCClosingStock = ((a.CPaobu ?? pac.COpeningStock ?? 0) + (ppv.Quantaty ?? 0)),
                                    DesignNoClosingStock = ((a.Dobu ?? 0) + (npv.Quantaty ?? 0)),
                                    DesignNoCClosingStock = ((a.CDobu ?? 0) + (ppv.Quantaty ?? 0))
                                };
                return l;


and this are the other functions helping this query 

  public static IQueryable<RsXtraOpeningStock> GetPackStock(RdbCompany con)
        {
            return con.RtbInventoryProductBrandPackDesignNoPairs
                .GroupBy(p => p.BrandPackPairId).Select(
                g => new RsXtraOpeningStock
                         {
                             Id = g.Key,
                             OpeningStock = (g.Sum(m => m.OpeningStock) ?? 0),
                             COpeningStock = (g.Sum(m => m.COpenigStock) ?? 0),
                         });
        }


        public static IQueryable<RsXtraOpeningStock> GetBrandStock(RdbCompany con)
        {
            return from d in con.RtbInventoryProductBrandPackPairs
                   join pk in GetPackStock(con) on d.Id equals pk.Id
                       into pkl
                   from pkd in pkl.DefaultIfEmpty()
                   group new{d,pkd} by d.BrandPairId
                       into g
                       select new RsXtraOpeningStock
                       {
                           Id = g.Key,
                           OpeningStock = ((g.Sum(a => (decimal?)(a.d.OpeningStock ?? a.pkd.OpeningStock))??0)),
                           COpeningStock = ((g.Sum(a => (decimal?)(a.d.COpenigStock ?? a.pkd.COpeningStock))??0))
                       };
        }


        public static IQueryable<RsXtraOpeningStock> GetProductStock(RdbCompany con)
        {
            return from d in con.RtbInventoryProductBrandPairs
                   join br in GetBrandStock(con) on d.Id equals br.Id
                       into brl
                   from brd in brl.DefaultIfEmpty()
                   group new { d, brd } by d.ProductId
                       into g
                       select new RsXtraOpeningStock
                       {
                           Id = g.Key,
                           OpeningStock = ((g.Sum(a => (decimal?)(a.d.OpeningStock ?? a.brd.OpeningStock)) ?? 0)),
                           COpeningStock = ((g.Sum(a => (decimal?)(a.d.COpenigStock ?? a.brd.COpeningStock)) ?? 0))
                       };

        }






 public static IQueryable<RsXtraItemFinalBuySellByMode> GetTotalBuySellByItemForPure(RdbCompany con)
        {
            var stockActiveArray = RsXtraVoucherHelperArray.GetActiveStockVoucherType();
            return GetList(con).Where(
                a => stockActiveArray.Contains(a.FkVoucherVoMain.FkVoucher.FkVoucherGroup.VoucherType)
                     && a.FkVoucherVoMain.CompanyId == RsXtraMainInnerObj.CurrentCompany.Id
                     && a.FkVoucherVoMain.BranchId == RsXtraMainInnerObj.CurrentHierarchy.Id
                     && a.FkVoucherVoMain.Mode == RenumMode.P
                )
                .GroupBy(a => new {a.ItemId})
                .Select(a => new RsXtraItemFinalBuySellByMode
                                 {
                                     ItemId = a.Key.ItemId,
                                     Quantaty = a.Sum(c => (decimal?)c.Quantaty)
                                 });
        }


         public static IQueryable<RsXtraItemFinalBuySellByMode> GetTotalBuySellByItemForNormal(RdbCompany con)
        {
            var stockActiveArray = RsXtraVoucherHelperArray.GetActiveStockVoucherType();
            return GetList(con).Where(
                a => stockActiveArray.Contains(a.FkVoucherVoMain.FkVoucher.FkVoucherGroup.VoucherType)
                     && a.FkVoucherVoMain.CompanyId == RsXtraMainInnerObj.CurrentCompany.Id
                     && a.FkVoucherVoMain.BranchId == RsXtraMainInnerObj.CurrentHierarchy.Id
                     && a.FkVoucherVoMain.Mode != RenumMode.P
                )
                .GroupBy(a => new { a.ItemId })
                .Select(a => new RsXtraItemFinalBuySellByMode
                {
                    ItemId = a.Key.ItemId,
                    Quantaty = a.Sum(c => (decimal?)c.Quantaty)
                });
        }

2 个答案:

答案 0 :(得分:0)

如果使用Linq to SQL,您可以看到通过SQL Server配置文件准确生成的SQL语句。您可以根据它来优化它。但加入这么多物体后,性能可能会明显丧失。

答案 1 :(得分:0)

我怀疑您会发现每次主查询调用您的帮助函数时都会重新评估,您应该能够通过在主查询上执行ToString()来确认这一点。并检查编译器生成的方法语法。如果我是你,我会事先为每个可能的输入缓存帮助器的结果,并将结果存储在Dictionaries中,然后主查询可以在O(1)时间内查找。