I have a problem with query, please take a look. My aim is:
- I need to take all
Productswith oneImage. ProductshasValueswhich are some additional information aboute the product like specification etc.ImageandValuescan benull- Wanna return all
ProductswithImageandValues - For
ValuesI need onlyIdsso its ok to getList<int> of Values ProductValuesandImageObjectsare connecting table for relationship -->Productscan have manyProductValuesalsoProductscan have manyImageObjectsbut can have oneImageDistinctByis frommore linq
Question I don't know how to aggregate Values in correct way to return list of Values per Product
PS I'm also using more linq
var q1 = (from p in Products
join pv in ProductValues on p.ProductId equals pv.ProductId into ljpv
from pv in ljpv.DefaultIfEmpty()
select new
{
ProductId = p.ProductId,
Description = p.Description,
Name = p.Name,
Price = p.Price,
Quantity = p.Quantity,
Type = p.Type,
Values = (from v in ValueTypes
where v.ValueId == pv.ValueId
select new {
ValueId = v.ValueId
}).ToList(),
ImageObjects = (from io in ImageObjects
where io.ProductId == p.ProductId && io.IsDefault == true
select new
{
Image = io.Image,
IsDefault = io.IsDefault,
ProductId = io.ProductId
})
.ToList()
})
.DistinctBy(x=>x.Name)
.OrderBy(x=>x.Name);
q1.Dump();
Answer
Values = (from tmp in ljpv select new { ValueId = tmp.ValueId}),
I know that this is not place to answer, but meaby someone will have any addvices to my code or meaby it can be done more clear or faster. I've been wondering how to do this query for a long time, but as I wrote to you, I got a dazzle:)
after @Harald Coppoolse answer - the code is more faster!
return context.Product.GroupJoin(
context.ProductValue,
context.ImageObject.Include(x => x.Image),
p => p.ProductId,
pv => pv.ProductId,
io => io.ProductId,
(p, pv, io) => new ProductModel
{
ProductId = p.ProductId,
Name = p.Name,
Price = p.Price,
ProductValue = pv
.Select(npv => new ProductValueModel
{
ProductId = npv.ProductId,
}).ToList(),
ImageObject = io
.Select(nio => new ImageObjectModel
{
Image = nio.Image.DtoToModel(),
IsDefault = nio.IsDefault,
ProductId = nio.ProductId
}).ToList(),
});
So you have a table of
Productsand a table ofProductValueswith a one-to-many relation: everyProducthas zero or moreProductValuesand everyProductValuebelongs to exactly oneProduct, namely theProductthat the foreign keyProductIdpoints to.You want (several properties of) all
Products, eachProductwith itsProductValues. After that youDistinctByandOrderBy, but that is not your problem.Whenever you want "items with their sub-items", like "Schools with their Students", "Customers with their Orders", "Orders with their Order lines", consider using Enumerable.GroupJoin
GroupJoin is in fact a Left Outer Join, followed by a GroupBy.
In your case, you don't want to GroupJoin two sequences, but three sequences. You'l need to do an extra GroupJoin:
This looks horrible. So if you have to do a GroupJoin with three tables more often, consider to create a GroupJoin for three tables:
usage: