如何在EF核心中选择与其他实体有关系的实体



如何在不包括项目的情况下获得特定项目的产品列表?类似的东西

select p.Id, p.Name 
from product p
inner join ProjectProduct j on p.Id = j.ProductId and j.ProjectId = @Id

我拥有的最接近的解决方案是

var products = await (from proj in context.Project select proj)
.Where(proj => proj.Id == 1)
.Select(proj => proj.Product)
.ToListAsync();

但这返回一个List<List<Product>>此外,我还需要能够添加order by和pagination我知道我可以通过像这样的原始sql来完成

var param1 = new SqlParameter("@Id", id);
var query = @"select * from product p
inner join ProjectProduct j
on p.Id = j.ProductId and j.ProjectId = @Id ";
var queryable = context.product.FromSqlRaw(query, param1).AsQueryable();
await HttpContext.AddPaginationToHeader(queryable);
var products = await queryable.OrderBy(x => x.Name).Paginate(paginationDTO).ToListAsync();

但我希望通过linq来实现

public class Project
{
public int Id { get; set; }
public string Name { get; set; }
public List<Product> Product { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public List<Project> Project { get; set; }
}
public class ProjectProduct
{
public int ProjectId { get; set; }
public int ProductId { get; set; }
}

感谢Harald Coppoolse在另一篇帖子上的回应对于那些有同样问题的

这是台阶1-我们将查询定义为可查询

var queryable = context.Project
.Where(proj => proj.Id == id)
.SelectMany(p => p.Product).AsQueryable();

2-现在我们可以像一样将查询传递到SQL服务器

var products = await queryable.OrderBy(x => 
x.Name).Skip(...).Take(...).ToListAsync();

对于Skip和Take,我们可以为IQueryable创建一个通用扩展并在返回的基础上添加一种方法

return queryable
.Skip((paginationDTO.Page - 1) * paginationDTO.PageSize)
.Take(paginationDTO.PageSize);

当然,我们的paginationDTO只不过是一个具有page和pageSize 两个属性的POCO类

试试这个:

var products = await  context.Project
.Where(proj => proj.Id == 1)
.Select( proj=>proj.Products)
.FirstOrDefaultAsync();

如果你想在这之后订购产品,你可以用这种常见的方式

products= products.OrderBy(p=>p.Name).ToList();

它可以放在一行中,但EF有时会生成一个非常荒谬的Sql脚本,所以最好单独执行。

相关内容

最新更新