简体   繁体   中英

How can I improve this LINQ query?

I fear that I'm doing n+1 query here, how can I improve this?

var inventories = AppContext.Inventories
                            .GroupBy(i => new { i.LocationId, i.ProductId })
                            .Select(g => new InventoryAvailableQuantity
                            {
                                ProductId = g.Key.ProductId,
                                LocationId = g.Key.LocationId,
                                Product = g.FirstOrDefault().Product.Name,
                                Location = g.FirstOrDefault().Location.Name,
                                PurchasePrice = AppContext.Inventories.Where(i => i.ProductId == g.Key.ProductId).OrderByDescending(i => i.DateAdded).FirstOrDefault().PurchasePrice,
                                ResellerPrice = AppContext.Inventories.Where(i => i.ProductId == g.Key.ProductId).OrderByDescending(i => i.DateAdded).FirstOrDefault().ResellerPrice,
                                RetailPrice = AppContext.Inventories.Where(i => i.ProductId == g.Key.ProductId).OrderByDescending(i => i.DateAdded).FirstOrDefault().RetailPrice
                            }).ToList();

You can use comprehension instead of method and gain the ability to use "let":

var inventories = from inv in AppContext.Inventories
                  group inv by new { i.LocationId, i.ProductId } into g
                  let firstInv = g.FirstOrDefault()
                  let firstPur = AppContext.Inventories
                                        .Where(i => i.ProductId == g.Key.ProductId)
                                        .OrderByDescending(i => i.DateAdded)
                                        .FirstOrDefault()
                  select new InventoryAvailableQuantity
                  {
                      ProductId = g.Key.ProductId,
                      LocationId = g.Key.LocationId,
                      Product = firstInv.Product.Name,
                      Location = firstInv.Location.Name,
                      PurchasePrice = firstPur.PurchasePrice,
                      ResellerPrice = firstPur.ResellerPrice,
                      RetailPrice = firstPur.RetailPrice
                  }; // ( select ... { ... }).ToList(); if you will

Fast answer

        var inventories = Inventories
            .GroupBy(i => new {i.LocationId, i.ProductId})
            .Select(g => new
            {
                g.Key.ProductId,
                g.Key.LocationId,
                CurrentInventories = g.FirstOrDefault(),
                LastInventories = Inventories.Where(i => i.ProductId == g.Key.ProductId).OrderByDescending(i => i.DateAdded).FirstOrDefault()
            })
            .Select(g => new InventoryAvailableQuantity
            {
                ProductId = g.ProductId,
                LocationId = g.LocationId,
                Product = g.CurrentInventories.Product.Name,
                Location = g.CurrentInventories.Location.Name,
                PurchasePrice = g.LastInventories.PurchasePrice,
                ResellerPrice = g.LastInventories.ResellerPrice,
                RetailPrice = g.LastInventories.RetailPrice
            })
            .ToList();

You can take last item after grouping and take what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM