C# 实体框架-根据子实体条件筛选和检索子实体

C# 实体框架-根据子实体条件筛选和检索子实体,c#,asp.net,.net,entity-framework,.net-core,C#,Asp.net,.net,Entity Framework,.net Core,我的问题如下:我有一个产品实体,如下所示: 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 D

我的问题如下:我有一个
产品
实体,如下所示:

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; }
所以,我有一个控制器路径,在这里我想检索所有的产品,只检索那些图像,它们是主要的产品图像(大多数情况下,它将只是一个图像,但我仍然喜欢返回它们的列表)

目前,我尝试做的事情不起作用:

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);
}
我需要的是:

[
    {
        "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"
        }
    }
]

提前感谢

不要在产品上选择,而是尝试在图像上选择:

public async Task<PagedList<Product>> GetProducts(UserParams userParams)
{
     var productsFromRepo = context.Images
         .Where(i => i.IsMain)
         .Select(i => new Product {
             Id = i.Product.Id,
             Title = i.Product.Title,
             ...
             Images = new List<Image>{ i }
         })
         .OrderByDescending(b => b.Published)
         .AsQuerable();

     return await PagedList<Product>.CreateAsync(productsFromRepo, userParams.PageNumber, userParams.PageSize);
}
公共异步任务GetProducts(UserParams UserParams) { var productsFromRepo=context.Images .其中(i=>i.IsMain) .选择(i=>新产品{ Id=i.Product.Id, Title=i.Product.Title, ... 图像=新列表{i} }) .OrderByDescending(b=>b.Published) .AsQuerable(); 返回wait PagedList.CreateAsync(productsFromRepo、userParams.PageNumber、userParams.PageSize); }
不要在产品上选择,而是尝试在图像上选择:

public async Task<PagedList<Product>> GetProducts(UserParams userParams)
{
     var productsFromRepo = context.Images
         .Where(i => i.IsMain)
         .Select(i => new Product {
             Id = i.Product.Id,
             Title = i.Product.Title,
             ...
             Images = new List<Image>{ i }
         })
         .OrderByDescending(b => b.Published)
         .AsQuerable();

     return await PagedList<Product>.CreateAsync(productsFromRepo, userParams.PageNumber, userParams.PageSize);
}
公共异步任务GetProducts(UserParams UserParams) { var productsFromRepo=context.Images .其中(i=>i.IsMain) .选择(i=>新产品{ Id=i.Product.Id, Title=i.Product.Title, ... 图像=新列表{i} }) .OrderByDescending(b=>b.Published) .AsQuerable(); 返回wait PagedList.CreateAsync(productsFromRepo、userParams.PageNumber、userParams.PageSize); }
在我看来,匿名对象没有任何帮助。您可以在从数据库检索产品图片后对其进行过滤,或者如果要阻止EF将其从数据库中取出,请使用查询过滤器

检查此项以获得清晰的图片

这样做的目的是在pictures实体的fluent api配置中包括查询过滤器:

builder.HasQueryFilter(p => p.IsMain);
默认情况下,这将阻止EF检索未设置为主的图片。如果您希望EF检索所有图片(即图片索引中的图片),则必须使用

.IgnoreQueryFilters()
在您的查询中


另外,我没有包含完整的代码片段,如果您觉得没有意义,请让我演示完整的代码。

嗯,我认为匿名对象没有帮助。您可以在从数据库检索产品图片后对其进行过滤,或者如果要阻止EF将其从数据库中取出,请使用查询过滤器

检查此项以获得清晰的图片

这样做的目的是在pictures实体的fluent api配置中包括查询过滤器:

builder.HasQueryFilter(p => p.IsMain);
默认情况下,这将阻止EF检索未设置为主的图片。如果您希望EF检索所有图片(即图片索引中的图片),则必须使用

.IgnoreQueryFilters()
在您的查询中


另外,我没有包含完整的代码片段,如果您觉得没有意义,请让我演示完整的代码。

实体反映数据状态,而仅反映数据状态。如果您想为视图筛选结果,这是一个单独的问题。不要将实体发送到视图,而是将ViewModels发送到视图。视图模型将表示视图所需的数据,并且仅表示视图所需的数据,即视图所期望的方式。实体暴露了太多关于域模型的信息,如果服务器代码不整洁,会使您面临意外的性能问题和篡改。@StevePy这不是您看到的我的控制器方法。这是存储库方法。我不是返回普通实体,而是返回一个DTO,在这里我为控制器选择必要的数据以返回。因此,感谢您的注意,但问题并不完全在于此。
var productsToReturn=productsFromRepo.Select(i=>i.Product)
反映了一个产品实体。要返回DTO,应使用
Select
使用产品和“主”图像投影到DTO。例如,
productsFromRepo.Select(I=>newproductdto{ProductId=I.Product.ProductId,/*etc*/Images=I.Images.Select(x=>newimagedto{/*将所需图像属性转换为DTO*/}).ToList()}
使用产品的详细信息编写产品DTO,以及从过滤结果填充图像,而不是返回产品实体。实体反映数据状态,并且仅反映数据状态。如果您想为视图筛选结果,这是一个单独的问题。不要将实体发送到视图,而是将ViewModels发送到视图。视图模型将表示视图所需的数据,并且仅表示视图所需的数据,即视图所期望的方式。实体暴露了太多关于域模型的信息,如果服务器代码不整洁,会使您面临意外的性能问题和篡改。@StevePy这不是您看到的我的控制器方法。这是存储库方法。我不是返回普通实体,而是返回一个DTO,在这里我为控制器选择必要的数据以返回。因此,感谢您的注意,但问题并不完全在于此。
var productsToReturn=productsFromRepo.Select(i=>i.Product)
反映了一个产品实体。要返回DTO,应使用
Select
使用产品和“主”图像投影到DTO。例如,
productsFromRepo.Select(I=>newproductdto{ProductId=I.Product.ProductId,/*etc*/Images=I.Images.Select(x=>newimagedto{/*将所需图像属性转换为DTO*/}).ToList()}
使用产品的详细信息编写产品DTO,并从筛选结果中填充图像,而不是返回产品实体。此解决方案的问题是,如果我的产品根本没有图像,它将不在列表中。因此,我需要所有有或没有主图像的产品,只有当它们有一个或多个图像时,才返回主图像。谢谢你的回答,这几乎是我需要的。这是一个很好的观点。你有公司吗