【发布时间】:2020-11-09 02:36:32
【问题描述】:
我的问题如下:我有一个Product 实体,看起来像这样:
public int Id { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string Excerpt { get; set; }
public string Description { get; set; }
public virtual Category Category { get; set; }
public DateTime Published { get; set; }
public string[] Tags { get; set; }
public int PublisherId { get; set; }
public virtual User Publisher { get; set; }
public virtual ICollection<MyImage> Images { get; set; }
现在这个Product 实体可以有许多Images(作为子实体),如下所示:
public int Id { get; set; }
public string Description { get; set; }
public DateTime DateAdded { get; set; }
public bool IsMain { get; set; }
public byte[] Image { get; set; }
public virtual Product Product { get; set; }
public int ProductId { get; set; }
所以,我有一个控制器路由,我想在其中检索所有产品,并且只检索那些作为主要产品图像的图像(大多数情况下,它只是一个图像,但我仍然更喜欢返回它们的列表)。
目前,我正在尝试做的事情不起作用:
public async Task<PagedList<Product>> GetProducts(UserParams userParams)
{
var productsFromRepo = context.Products
.Select(p => new {
Product = p,
Images = p.Images.Where(i => i.IsMain)
})
.OrderByDescending(b => b.Product.Published);
var productsToReturn = productsFromRepo.Select(i => i.Product).AsQueryable();
return await PagedList<Product>.CreateAsync(productsToReturn, userParams.PageNumber, userParams.PageSize);
}
我尝试获取所有产品及其主要图片。并返回带有主图像的产品,而不是所有图像。如您所见,我返回了一个PagedList 对象,我需要将IQueryable 作为CreateAsync 方法的第一个参数传递。
问题是,我设法对我的匿名投影对象 (productsFromRepo) 进行了过滤。但我不知道如何将该匿名对象作为带有过滤图像列表的产品对象返回。
它总是返回所有图像,而不是按我的需要过滤。
在这个问题中,我必须有我最后投影的对象,在这种情况下,productsToReturn 是一个IQueryable 对象。
在我的项目中,我使用延迟加载。所以默认情况下所有子实体都是惰性加载的。
所以基本上,我得到的现在是:
[
{
"id": 2,
"title": "My First Product",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"category": "Uncategorized",
"price": 15.0,
"excerpt": "Lorem ipsum",
"tags": [
"Tag1",
"Tag2"
],
"images": [
{
"id": 1,
"description": "test",
"isMain": true,
"dateAdded": "2020-07-15T22:40:09.285481",
"image":"/9j/...."
},
{
"id": 2,
"description": "test1",
"isMain": false,
"dateAdded": "2020-07-15T23:15:44.74166",
"image":"/9j/...."
},
{
"id": 3,
"description": "test1",
"isMain": false,
"dateAdded": "2020-07-15T23:27:39.636685",
"image":"/9j/...."
}
],
"published": "2020-07-15T22:39:27.89482",
"publisher": {
"id": 1,
"name": null,
"lastName": null,
"email": "testemail@gmail.com"
}
}
]
而我需要的是:
[
{
"id": 2,
"title": "My First Product",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"category": "Uncategorized",
"price": 15.0,
"excerpt": "Lorem ipsum",
"tags": [
"Tag1",
"Tag2"
],
"images": [
{
"id": 1,
"description": "test",
"isMain": true,
"dateAdded": "2020-07-15T22:40:09.285481",
"image":"/9j/...."
},
],
"published": "2020-07-15T22:39:27.89482",
"publisher": {
"id": 1,
"name": null,
"lastName": null,
"email": "testemail@gmail.com"
}
}
]
提前致谢
【问题讨论】:
-
实体反映数据状态,并且仅反映数据状态。如果您想要为您的视图过滤结果,这是一个单独的问题。 不要将实体发送到视图,要将 ViewModel 发送到视图。 ViewModel 将表示您的视图需要的数据,并且仅表示您的视图需要的数据,以您的视图期望的方式。如果服务器代码草率,实体会暴露太多关于您的域模型的信息,并让您容易遇到意外的性能问题和篡改。
-
@StevePy 这不是您看到的我的控制器方法。这是存储库方法。我不是返回普通实体,而是返回一个 DTO,在那里我选择了该控制器返回的必要数据。感谢您的关注,但问题不完全是这样。
-
var productsToReturn = productsFromRepo.Select(i => i.Product)反映了一个产品实体。要返回 DTO,您应该使用Select使用产品和“主”图像投影到 DTO。 IE。productsFromRepo.Select(i => new ProductDTO { ProductId = i.Product.ProductId, /* etc */ Images = i.Images.Select(x => new ImageDTO { /* translate desired image properties to DTO */ }).ToList() })使用产品的详细信息编写产品 DTO,并根据过滤结果填充图像,而不是返回产品实体。
标签: c# asp.net .net entity-framework .net-core