【问题标题】:how to select entity with relationship to other entity in EF core如何在 EF 核心中选择与其他实体有关系的实体
【发布时间】:2021-07-09 20:06:33
【问题描述】:

如何在不包含项目的情况下获取特定项目的产品列表?类似于

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>> 另外我需要能够添加顺序和分页 我知道我可以通过这样的原始 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 to entity 来实现

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; }
}

【问题讨论】:

    标签: c# entity-framework linq asp.net-core .net-core


    【解决方案1】:

    感谢 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 and Take,我们可以为 IQueryable 创建一个通用扩展 并添加一个方法返回

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

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

    【讨论】:

      【解决方案2】:

      试试这个:

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

      如果你想在此之后订购产品,你可以这样做

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

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

      【讨论】:

      • 嗨,Serge 感谢您的回复,解决了列表> 的问题,但是我如何为产品应用 OrderBy
      • 很高兴能帮到你。请不要忘记接受答案(点击向下投票箭头下方的复选标记)
      • 你做 OrderBy 的方式发生在内存中,这不是我需要的方式,有没有办法在查询中添加 orderby?
      • 在 SQL 服务器内存或 Web 服务器内存中订购它们并不重要,因为您将下载相同的记录,只是以不同的顺序。恕我直言,如果您在下载后订购它们会更快。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多