我正在尝试从产品和产品图像表中选择带有产品图像的产品,其中产品图像表包含产品的图像,并且可以包含单个产品的空图像或多个图像。 我使用 sql 查询完成了此操作,但无法编写确切的 linq 查询
我的产品表是
ID | Name
______________________
1 | Masic Mouse
2 | IPhone X
3 | Thai Jeans pant
4 | Samsung Galaxy 8
5 | Apple Laptop
6 | round collar
7 | V collar t-shirt
我的产品图片表是
productId | Image | ProductImageId
_________________________________________________________________
1 | 14_mm01.jpg | 1
2 | new-1.jpg | 2
3 | jeans pant.jpeg | 3
4 | 21_samsung.jpg | 4
4 | 21_samsungghf.jpg | 5
5 | images.jpg | 6
6 | 21502057.jpg | 10
用于选择新表的SQL查询
SELECT p.id,
p.NAME,
Isnull((SELECT TOP 1 image
FROM productimages
WHERE productid = p.id), 'noproductimage.jpg') AS image,
Isnull((SELECT TOP 1 Cast(id AS VARCHAR(50))
FROM productimages
WHERE productid = p.id), 'NoId') AS ProductImageId
FROM products p
这给了我确切的结果,例如
ID | Name | Image | ProductImageId
_________________________________________________________________
1 | Masic Mouse | 14_mm01.jpg | 1
2 | IPhone X | new-1.jpg | 2
3 | Thai Jeans pant | jeans pant.jpeg | 3
4 | Samsung Galaxy 8 | 21_samsung.jpg | 4
5 | Apple Laptop | images.jpg | 6
6 | round collar | 21502057.jpg | 10
7 | V collar t-shirt | noproductimage.jpg | NoId
但是当我尝试使用 linq 执行此操作时,我没有得到像上表那样的预期结果。 我对此选择的LINQ查询是
var products = from p in db.Products
select new
{
p.Id,
p.Name,
ProductImage = (from ppi in db.ProductImages where
ppi.ProductId == p.Id
select ppi.Image),
ProductImageID = (from ppi in db.ProductImages
where ppi.ProductId == p.Id
select ppi.Id)
};
此LINQ查询仅返回一个结果
ID | Name | Image | ProductImageId
_________________________________________________________________
1 | Masic Mouse | 14_mm01.jpg | 1
如何获得与返回的 SQL查询完全相同的预期结果?
如果您在Products
和ProductImages
上执行 GroupJoin 会快得多。如果产品有任何图片,请选择名字和 ID 如果没有图像,请选择"noProductImage"和"NoId">
var result = products.GroupJoin(productImages, // GroupJoin products and productImages
product => product.Id, // from every product take the Id
image => image.ProductId, // from every image take the productId
(product, images) => new // for every product with matching images make new:
{
ProductId = product.Id,
Name = product.Name,
Image = images
.Select(image => image.Image)
.FirstOrDefault() ?? // select the first image name
"noproductimage.jpg", // or use a default if there is none
ProductImageId = images
.Select(image => image.ProductImageId.ToString())
.FirstOrDefault() ?? // select the text of the first productId
"NoId"); // or use a default if there is none
}
此语句必须检查两次是否有任何图像,就像您的 SQL 语句一样。
考虑将图像数据作为一个子类返回:
(product, images) => new // for every product with matching images make new:
{
ProductId = product.Id,
Name = product.Name,
ImageData = images.Select(image => new
{
Image = image.Image,
ProductImageId = image.ProductImageId.ToString(),
})
.FirstOrDefault() ?? // select the first image name
new // or use a default if there is none
{
Image = "noproductImage.jpg",
ProductImageId = "NoId",
},
});
最后评论:将 ProductImageId 作为数字而不是文本返回不是更好吗?让数字零表示"无 ID"。
var data =(from item in db.Product
join item1 in db.productImage on item.id equals item1.productId select new{
item.Id,
item.Name,
ProductImage = (item1.image==null)?”noproductimage.jpg” :item1.image,
productImageId= (item1.imageid==null) ?”NoId”: item1.imageid
}).groupBy(a=>a.productImageId).select(a=>a.firstOrDefault()).toList();
你为什么不加入两个表?