如何检查 null 并在 linq 匿名类型中分配新值以选择预期的 sql 结果



我正在尝试从产品和产品图像表中选择带有产品图像的产品,其中产品图像表包含产品的图像,并且可以包含单个产品的图像或多个图像。 我使用 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查询完全相同的预期结果?

如果您在ProductsProductImages上执行 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();

你为什么不加入两个表?

最新更新