0
When I took a code to improve performance I had the following. A method GetAll()
this method populated a var. It was made a foreach
in this var and was assigning the appropriate values. It happens that within this foreach
there was such a command:
if (product.PictureId.HasValue)
item.PictureFilename = product.Picture.FileName;
This condition is paramount. The problem that this foreach takes at least 4 min to execute and I speak of only 122 records (202 in Getall()). I did a lambda and reduced in Debug to 17s and environment to 6s to 10s. But the problem is in the code above. In lambda I can’t bring it: product.Picture.FileName
. Picture is a virtual property of Product(class) and Picture is a class as well. The lambda is not the instance and gives error of NullReferenceException
, of the kind:
Undefined object reference for an object instance.
There is some understanding missing in Linq/Lambda for me to complete this topic. This is the complete lambda that I did and the commented lines are the ones that are giving problem. Besides what I posted (original Lambda), I made several other attempts.
var qry = _productRepository.Table.GroupJoin(_categoriesRepository.Table,
p => p.CategoryId,
c => c.Id,
(p, c) => new { Product = p, Categories = c.DefaultIfEmpty() })
.Where(hdg => hdg.Product.Hidden == false)
.SelectMany(final => final.Categories,
(final, c) => new CatalogItemResponse
{
ChildrenCategoryId = final.Product.ChildrenCategoryId,
DolarRate = 0.0m,
ResellerPriceUSD = 0.0m,
ResellerPriceBRL = 0.0m,
BasePriceBRL = 0.0m,
BasePriceUSD = 0.0m,
CategoryId = final.Product.CategoryId,
CategoryName = (c != null ? c.Name : null),
PictureId = final.Product.PictureId,
Description = final.Product.Description,
ShortDescription = final.Product.ShortDescription,
Name = final.Product.Name,
NameHtml = string.IsNullOrEmpty(final.Product.NameHtml) ? final.Product.Name : final.Product.NameHtml,
PartNumber = final.Product.PartNumber,
Hidden = final.Product.Hidden,
Order = final.Product.Order,
HaveMaximumPercentage = final.Product.HaveMaximumPercentage,
MaximumPercentage = final.Product.MaximumPercentage,
HaveMinimumPercentage = final.Product.HaveMinimumPercentage,
MinimumPercentage = final.Product.MinimumPercentage,
AuthorizeMaximumPercentageAlteration = final.Product.AuthorizeMaximumPercentageAlteration,
AuthorizeMinimumPercentageAlteration = final.Product.AuthorizeMinimumPercentageAlteration,
StandardMarkup = final.Product.StandardMarkup,
DistributionCenterErpId = final.Product.DistributionCenterErpId,
PictureFilename = final.Product.Picture.FileName
}).ToList();
qry.ForEach(q =>
{
var product = new Product();
product.CategoryId = q.CategoryId;
product.AuthorizeMaximumPercentageAlteration = q.AuthorizeMaximumPercentageAlteration;
product.AuthorizeMinimumPercentageAlteration = q.AuthorizeMinimumPercentageAlteration;
product.HaveMaximumPercentage = q.HaveMaximumPercentage;
product.HaveMinimumPercentage = q.HaveMinimumPercentage;
product.Hidden = q.Hidden;
product.ChildrenCategoryId = q.ChildrenCategoryId;
product.Description = q.Description;
product.DistributionCenterErpId = q.DistributionCenterErpId;
product.MaximumPercentage = q.MaximumPercentage;
product.MinimumPercentage = q.MinimumPercentage;
product.Name = q.Name;
product.NameHtml = q.NameHtml;
product.Order = q.Order;
product.PartNumber = q.PartNumber;
product.PictureId = q.PictureId;
product.ShortDescription = q.ShortDescription;
product.StandardMarkup = q.StandardMarkup;
var parentProducts = _productService.GetParentsOf(product.Id).Select(x => x.PartNumber);
q.Parents.AddRange(parentProducts);
//if (product.PictureId.HasValue)
// q.PictureFilename = product.Picture.FileName;
var price = _erpPriceService.GetPrice(product, 1, resellerId).Result;
if (price.BasePriceUSD > 0)
q.DolarRate = price.BasePriceBRL / price.BasePriceUSD;
q.ResellerPriceUSD = price.ResellerPriceUSD;
q.ResellerPriceBRL = price.ResellerPriceBRL;
q.BasePriceBRL = price.BasePriceBRL;
q.BasePriceUSD = price.BasePriceUSD;
});
return qry;
When I give a new Product(), I already lose references to all the virtual properties in Product, correct? Outside the
ForEach()
lambda, I really don’t know where to assign the values that are within the if.– pnet
would have to post a project with only the essential, reproducing the problem, to be able to test on this side?
– vik
When I do
var product = new Product()
I’m killing Lazy loading and that leaves Picture out, right? And how do I keep Lazy loading?– pnet