I am trying to convert SQL to Linq that flattens two related tables into one record per parent table row (opposite of SelectMany).
My first attempt is below, but the resulting SQL is different although the result is the same. The example uses Product and ProductImage where a single Product can have multiple ProductImages.
Is my Ling correct and the SQL produced is equivalent, or what Linq can produce the SQL below?
Tables:
Product(productid int, name varchar(50))ProductImage(productid int, imageid int, imagepath varchar(450))ProductImage.productidis a foreign key pointing toProductProductImage.imageidis numbered 1,2,3,4 for eachProductImage
SQL select to flatten the first three photos of a product
select
p.productid, p.name,
i1.imagepath as i1imagepath,
i2.imagepath as i2imagepath,
i3.imagepath as i3imagepath
from
product as p
join
productimage as i1 on p.productid = i1.productid
join
productimage as i2 on p.productid = i2.productid
join
productimage as i3 on p.productid = i3.productid
where
i1.imageid = 1 and
i2.imageid = 2 and
i3.imageid = 3
First attempt at Linq to convert this query:
Product.Select( p => new { p.productid, p.name,
i1imagepath = p.ProductImage.AsQueryable()
.Where(i => i.imageid == 1)
.Select(i => i.imagepath).FirstOrDefault(),
i2imagepath = p.ProductImage.AsQueryable()
.Where(i => i.imageid == 2)
.Select(i => i.imagepath).FirstOrDefault(),
i3imagepath = p.ProductImage.AsQueryable()
.Where(i => i.imageid == 3)
.Select(i => i.imagepath).FirstOrDefault()
}).Take(1).Dump(); // LinqPad Dump()
but it produces this SQL instead of above which looks less efficient (a side note, the actual execution numbers for the below SQL are nearly half of the original SQL above.)
select top 1 p.productid, p.name,
(select top 1 p0.imagepath
from productimage as p0
where p.productid = p0.productid and
p0.imageid = 1) as i1imagepath,
(select top 1 p1.imagepath
from productimage as p1
where p.productid = p1.productid and
p1.imageid = 2) as i2imagepath,
(select top 1 p2.imagepath
from productimage as p2
where p.productid = p2.productid and
p2.imageid = 3) as i3imagepath
from product